zoukankan      html  css  js  c++  java
  • C#使用Google实现在线翻译 狼人:

    本文部分参考了GitHub中wadereye的代码,在源代码基础上修改了部分针对tkk的筛选及使用逻辑。

    由于谷歌的tkk值规则一直在变,且api的url也不是固定的,所以做了配置类,方便修改。

    全部代码

    GoogleTranslate主类:

     public static class GoogleTranslate
        {
            public static string TranslateChinese2English(string text)
            {
                return Translate(text, "zh-CN", "en");
            }
    
            /// <summary>
            /// 谷歌翻译
            /// </summary>
            /// <param name="text">待翻译文本</param>
            /// <param name="fromLanguage">自动检测:auto</param>
            /// <param name="toLanguage">中文:zh-CN,英文:en</param>
            /// <returns>翻译后文本</returns>
            public static string Translate(string text, string fromLanguage, string toLanguage)
            {
                CookieContainer cc = new CookieContainer();
                string GoogleTransBaseUrl = ConfigManager.Instance.GetGoogleTranslate_Url();
                var BaseResultHtml = GetResultHtml(GoogleTransBaseUrl, cc, "");
                Regex re = new Regex(ConfigManager.Instance.GetGoogleTranslate_tkkRegex());
                var TKK = re.Match(BaseResultHtml).ToString();//在返回的HTML中正则匹配TKK的值
                //通过js获取tkk值,本js源码在根目录放置,源码在后文
                var GetTkkJS = File.ReadAllText("./gettk.js");
                var tk = ExecuteScript("tk(\"" + text + "\",\"" + TKK + "\")", GetTkkJS);
                string googleTransUrl = string.Format(ConfigManager.Instance.GetGoogleTranslate_API(), fromLanguage, toLanguage, tk, HttpUtility.UrlEncode(text));
                var ResultHtml = GetResultHtml(googleTransUrl, cc, ConfigManager.Instance.GetGoogleTranslate_Url());
    
                return GetResultContent(ResultHtml);
            }
    
            /// <summary>
            /// 解析返回值(重要)
            /// </summary>
            /// <param name="resultHtml"></param>
            /// <returns></returns>
            private static string GetResultContent(string resultHtml)
            {
                string resultContent = "";
                if (!string.IsNullOrWhiteSpace(resultHtml))
                {
                    JToken tmp = Newtonsoft.Json.JsonConvert.DeserializeObject<JToken>(resultHtml);
                    var mainTranslationInfo = tmp[0];
                    //originalTextTranscription,translatedTextTranscription 留作备用,根据自己需求判断是否使用
                    string originalTextTranscription = null, translatedTextTranscription = null;
                    string[] translation = null;
                    GetMainTranslationInfo(mainTranslationInfo, out translation,
                    ref originalTextTranscription, ref translatedTextTranscription);
    
                    if (translation.Length > 0)
                        resultContent = string.Join("", translation);
    
                }
                return resultContent;
            }
    
            private static void GetMainTranslationInfo(JToken translationInfo, out string[] translate,
        ref string originalTextTranscription, ref string translatedTextTranscription)
            {
                List<string> translations = new List<string>();
    
                foreach (var item in translationInfo)
                {
                    if (item.Count() >= 5)
                        translations.Add(item.First.Value<string>());
                    else
                    {
                        var transcriptionInfo = item;
                        int elementsCount = transcriptionInfo.Count();
    
                        if (elementsCount == 3)
                        {
                            translatedTextTranscription = (string)transcriptionInfo[elementsCount - 1];
                        }
                        else
                        {
                            if (transcriptionInfo[elementsCount - 2] != null)
                                translatedTextTranscription = (string)transcriptionInfo[elementsCount - 2];
                            else
                                translatedTextTranscription = (string)transcriptionInfo[elementsCount - 1];
    
                            originalTextTranscription = (string)transcriptionInfo[elementsCount - 1];
                        }
                    }
                }
    
                translate = translations.ToArray();
            }
    
    
            private static string GetResultHtml(string url, CookieContainer cookie, string referer)
            {
                var html = "";
                var webRequest = WebRequest.Create(url) as HttpWebRequest;
                webRequest.Method = "GET";
                webRequest.CookieContainer = cookie;
                webRequest.Referer = referer;
                webRequest.Timeout = 20000;
                webRequest.Headers.Add("X-Requested-With:XMLHttpRequest");
                webRequest.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
                webRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36";
                using (var webResponse = (HttpWebResponse)webRequest.GetResponse())
                {
                    using (var reader = new StreamReader(webResponse.GetResponseStream(), Encoding.UTF8))
                    {
                        html = reader.ReadToEnd();
                        reader.Close();
                        webResponse.Close();
                    }
                }
                return html;
            }
    
            /// <summary>
            /// 执行JS
            /// </summary>
            /// <param name="sExpression">参数体</param>
            /// <param name="sCode">JavaScript代码的字符串</param>
            /// <returns></returns>
            private static string ExecuteScript(string sExpression, string sCode)
            {
                MSScriptControl.ScriptControl scriptControl = new MSScriptControl.ScriptControl();
                scriptControl.UseSafeSubset = true;
                scriptControl.Language = "JScript";
                scriptControl.AddCode(sCode);
                try
                {
                    string str = scriptControl.Eval(sExpression).ToString();
                    return str;
                }
                catch (Exception ex)
                {
                    string str = ex.Message;
                }
                return null;
            }
    
        }
    

    配置类

    通过读取配置文件给主类传值,方便修改:

      public class ConfigHelper
        {
    
            ///<summary> 
            ///返回*.exe.config文件中appSettings配置节的value项  
            ///</summary> 
            ///<param name="strKey"></param> 
            ///<returns></returns> 
            public string GetAppConfig(string strKey)
            {
                string file = System.Windows.Forms.Application.ExecutablePath;
                Configuration config = ConfigurationManager.OpenExeConfiguration(file);
                foreach (string key in config.AppSettings.Settings.AllKeys)
                {
                    if (key == strKey)
                    {
                        return config.AppSettings.Settings[strKey].Value.ToString();
                    }
                }
                return null;
            }
    
            ///<summary>  
            ///在*.exe.config文件中appSettings配置节增加一对键值对  
            ///</summary>  
            ///<param name="newKey"></param>  
            ///<param name="newValue"></param>  
            public void AddAppConfig(string newKey, string newValue)
            {
                string file = System.Windows.Forms.Application.ExecutablePath;
                Configuration config = ConfigurationManager.OpenExeConfiguration(file);
                bool exist = false;
                foreach (string key in config.AppSettings.Settings.AllKeys)
                {
                    if (key == newKey)
                    {
                        exist = true;
                    }
                }
                if (exist)
                {
                    config.AppSettings.Settings.Remove(newKey);
                }
                config.AppSettings.Settings.Add(newKey, newValue);
                config.Save(ConfigurationSaveMode.Modified);
                ConfigurationManager.RefreshSection("appSettings");
            }
    
        }
    
        public class ConfigManager : ConfigHelper
        {
    
            public static ConfigManager Instance = new ConfigManager();
            public string GetGoogleTranslate_Url()
            {
                string value= GetAppConfig("GoogleTranslate_Url");
                if (string.IsNullOrWhiteSpace(value))
                    value = "https://translate.google.cn/";
                return value;
            }
            public string GetGoogleTranslate_API()
            {
                string value = GetAppConfig("GoogleTranslate_API");
                if (string.IsNullOrWhiteSpace(value))
                    value = "https://translate.google.cn/translate_a/single?client=webapp&sl={0}&tl={1}&hl=zh-CN&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=sos&dt=ss&dt=t&otf=1&pc=1&ssel=3&tsel=0&xid=45662847&kc=2&tk={2}&q={3}";
                return value;
            }
            public string GetGoogleTranslate_tkkRegex()
            {
                string value = GetAppConfig("GoogleTranslate_tkkRegex");
                if (string.IsNullOrWhiteSpace(value))
                    value = "(?<=tkk:')(.*?)(?=')";
                return value;
            }
        }
    

    App.config配置:

     <appSettings>
        <add key="GoogleTranslate_Url" value="https://translate.google.cn/"></add>
        <add key="GoogleTranslate_API" value="https://translate.google.cn/translate_a/single?client=webapp&amp;sl={0}&amp;tl={1}&amp;hl=zh-CN&amp;dt=at&amp;dt=bd&amp;dt=ex&amp;dt=ld&amp;dt=md&amp;dt=qca&amp;dt=rw&amp;dt=rm&amp;dt=sos&amp;dt=ss&amp;dt=t&amp;otf=1&amp;pc=1&amp;ssel=3&amp;tsel=0&amp;xid=45662847&amp;kc=2&amp;tk={2}&amp;q={3}"></add>
        <add key="GoogleTranslate_tkkRegex" value="(?&lt;=tkk:')(.*?)(?=')"></add>
      </appSettings>
    

    gettk.js

    本js文件保存在根目录(文件名:gettk.js),供GoogleTranslate类调用,获取tkk:

    //该文件用来获取谷歌翻译tkk值,不能删除,根据谷歌服务的变化有可能需要修改部分代码
    var b = function (a, b) {
        for (var d = 0; d < b.length - 2; d += 3) {
            var c = b.charAt(d + 2),
                c = "a" <= c ? c.charCodeAt(0) - 87 : Number(c),
                c = "+" == b.charAt(d + 1) ? a >>> c : a << c;
            a = "+" == b.charAt(d) ? a + c & 4294967295 : a ^ c
        }
        return a
    }
    
    var tk = function (a, TKK) {
        for (var e = TKK.split("."), h = Number(e[0]) || 0, g = [], d = 0, f = 0; f < a.length; f++) {
            var c = a.charCodeAt(f);
            128 > c ? g[d++] = c : (2048 > c ? g[d++] = c >> 6 | 192 : (55296 == (c & 64512) && f + 1 < a.length && 56320 == (a.charCodeAt(f + 1) & 64512) ? (c = 65536 + ((c & 1023) << 10) + (a.charCodeAt(++f) & 1023), g[d++] = c >> 18 | 240, g[d++] = c >> 12 & 63 | 128) : g[d++] = c >> 12 | 224, g[d++] = c >> 6 & 63 | 128), g[d++] = c & 63 | 128)
        }
        a = h;
        for (d = 0; d < g.length; d++) a += g[d], a = b(a, "+-a^+6");
        a = b(a, "+-3^+b+-f");
        a ^= Number(e[1]) || 0;
        0 > a && (a = (a & 2147483647) + 2147483648);
        a %= 1E6;
        return a.toString() + "." + (a ^ h)
    }
    

    使用

    直接调用主类的公用方法即可:

     GoogleTranslate.TranslateChinese2English("需要翻译内容");
    

    示例:

    private void button1_Click(object sender, EventArgs e)
    {
    	richTextBox2.Text = GoogleTranslate.TranslateChinese2English(richTextBox1.Text);
    }
    

    在这里插入图片描述

    作者:Mr.Jimmy
    出处:https://www.cnblogs.com/JHelius
    联系:yanyangzhihuo@foxmail.com
    如有疑问欢迎讨论,转载请注明出处

    声明:此博有部分内容为转载,版权归原作者所有~
  • 相关阅读:
    @override报错
    idea快捷键
    java中getAttribute与getParameter的区别
    localStorage基于浏览器的本地存储
    js画布组件(<canvas></canvas>)
    easyui
    关于Bootstrap
    使用layUI美化的登录功能
    EXT JS
    ★一些文章链接
  • 原文地址:https://www.cnblogs.com/waw/p/15635529.html
Copyright © 2011-2022 走看看