C#(.NET)爬取Bing翻译

725 阅读2分钟

进入正题之前,先给几个大厂提供的免费试用的翻译API

  • 百度

通用文本翻译API:标准版免费调用量调整为5万字符/月,高级版免费调用量调整为100万字符/月。

地址:fanyi-api.baidu.com/product/11

  • 腾讯

通用文本翻译API:每月免费额度为5百万字符。

地址:fanyi.qq.com/translateap…

  • 华为

通用文本翻译API:0~100万字符不收费

地址:www.huaweicloud.com/product/nlp…

先说爬取网站翻译这个行为咱们是不提倡的,但是有时候受限于各种原因又不得不作为临时方案使用下,故才去看怎么抓取下Bing的页面翻译。

首先我们通过浏览器打开Bing的站点:cn.bing.com/translator; F12打开开发者模式,通过观察网络请求发现“cn.bing.com/ttranslatev… 这个请求就是我们的目标,既然是Api接口那就好办了。

image.png

image.png

image.png

好了,该接口是个POST请求,请求类型是application/json; charset=utf-8,但实际请求参数却要放在表单里,同时url需要带参,ok,postman模拟起来。

image.png

照搬请求在post模拟起来没问题,让我们来先来分析下application/x-www-form-urlencoded的参数,首先formlang、text、to一眼就能认出来分别是待翻译文本语言代码、待翻译文本、译文语言代码。这两个没问题,那么剩下的token和key估摸着就是认证的东西,其他不变随便修改下这两个参数的值。

image.png

确实不行,那么这个token和key怎么来的呢,既然是页面请求那么必然有存储的地方,直接copy该Key的值去页面检索下,误打误撞被我们发现了个啥

image.png

image.png

这么一组字符串:[1694663424321,"82S4gDwbr-EjWL4d-EEUHC2HMp2AAOtB",3600000] 那么key,token,甚至失效时间我们都有了,开始编码。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Threading.Tasks;

namespace BingTranslator
{
    public class TranslatorHelper
    {
        static HttpClient _client = new();
        public TranslatorHelper()
        {
        }

        /// <summary>
        /// 翻译-爬取Bing网页翻译
        /// 常用语言代码:
        /// 中文简体:zh-Hans
        /// 中文繁体:zh-Hant
        /// 英文:en
        /// 其他代码可去bing翻译网站查看下拉框的Value值
        /// </summary>
        /// <param name="orgText">原文</param>
        /// <param name="fromLang">原文语言代码</param>
        /// <param name="to">译文语言代码</param>
        /// <returns></returns>
        public static async Task<string> Translate(string orgText, string fromLang = "zh-Hans", string to = "en")
        {
            try
            {
                var token = "";
                var key = "";
                //获取Token 和Key
                var url = "https://cn.bing.com/translator";
                var html = await _client.GetAsync(url);
                if (html.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    var result = await html.Content.ReadAsStringAsync();
                    var tokenkey = "params_AbusePreventionHelper =";
                    var index = result.IndexOf(tokenkey) + tokenkey.Length;
                    if (index < 0) return "";
                    var jo = JsonSerializer.Deserialize<object[]>(result.Substring(index, 59));
                    key = jo[0].ToString();
                    token = jo[1].ToString();
                }

                url = "https://cn.bing.com/ttranslatev3?isVertical=1&IG=D472EE7442D341998F23205672BE0D85&IID=translator.5027";
                var postData = $"&fromLang={fromLang}&text={orgText}&to={to}&token={token}&key={key}&tryFetchingGenderDebiasedTranslations=true";
                var content = new StringContent(postData);
                content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/x-www-form-urlencoded");
                var res = await _client.PostAsync(url, content);
                if (res.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    var resultJson = await res.Content.ReadAsStringAsync();
                    if (string.IsNullOrEmpty(resultJson)) return "";
                    var transObj = JsonSerializer.Deserialize<JsonNode>(resultJson);
                    return transObj?[0]?["translations"]?[0]?["text"]?.ToString() ?? "";
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
            return "";
        }
    }
     
}

至此,一个简单基于.NET6的C#爬取Bing页面翻译的方法我们就写好了。