利用Google進行無長度限制的文本翻譯(無需API,無需Money)


 

背景介紹

  前段時間在做一個類似於“一鍵翻譯”的小功能,需要對長文本進行多語種的翻譯,本以為很簡單,不過在網上找來找去,居然發現沒有一個完美的方法來解決,我只好從網上搜來了各種各樣的翻譯API,並揣摩了其使用方法,不過都不盡完美,其各方面的缺陷大致有:

  • 微軟API:利用WCF方式進行翻譯,每次翻譯英文字數最大為一萬兩千多個,中文字符的話最多為六七千個,最大200M字符/月的限制,超過限制后要付費。對HTML翻譯支持完美,翻譯結果也不錯,但考慮到免費字符數限制,需做賬號輪巡,賬號注冊的步驟那叫一個繁瑣啊……(此方式可做為首選翻譯方式,輪巡的翻譯功能已實現,有時間了把源碼貼上來。  ——qfzhang於2013-05-30更新)
  • YoudaoAPI:語言支持不夠多,只有英文、日文、中文幾個之間的互相翻譯,且每次請求最多翻譯的字符數不能超過200,還有訪問頻率限制。
  • GoogleAPI:Google翻譯的API,優勢明顯,翻譯結果十分准確,尤其是針對HTML,能夠准確跳過HTML標簽部分,只翻譯文本,但它是付費使用的(v1版為免費版,但接口已關閉),其價格為100萬字符/20美金,其價格自然不言而喻。且在使用過程中發現,其標稱每次最大翻譯字符數不能超過2k,但實際使用時超過1.5k就會報異常。
  • BaiduAPI:有訪問頻率限制和長度限制,且翻譯結果不理想。

 在這四大翻譯巨頭的各種限制之下,不得不另尋出路……

 

轉機

  鑒於Google翻譯的准確性,還是果斷選擇了Google作為目標,但其價格實在昂貴,只好從其翻譯頁面上做文章。

  在測試時發現,其GET請求中加上一些參數可以實現翻譯功能,於是乎第一個GET版本的翻譯功能出爐了,其步驟大約分為以下兩步:

  • 構造查詢字符串,向翻譯頁面發送請求
  • 獲取返回的HTML,並從中過濾出所需要的結果。(小弟不才,因為這個東西,好好地把正則表達式訓練了一把^_^)

  然而,GET方式跟API有同樣的問題,超出固定長度后就會報請求異常。於是只能再想其它方法。

  后來小弟嘗試了構造POST請求去訪問它,沒想到……居然成功了……一時高興,代碼不敢獨享,在此貼出來,希望大家有遇到此類問題的,一起分享一下。

 

源代碼:

1.代碼部分

1). 翻譯者接口,為以后擴展使用

View Code
using System;
namespace Common.Translator
{
    /// <summary>
    /// 語言翻譯者接口
    /// ZhangQingFeng    2012-7-27    add
    /// </summary>
    public interface ITranslator
    {
        /// <summary>
        /// 翻譯文本
        /// ZhangQingFeng    2012-7-27    add
        /// </summary>
        /// <param name="sourceText">源文本</param>
        /// <param name="sourceLanguageCode">源語言類型代碼,如:en、zh-CN、zh-TW、ru等</param>
        /// <param name="targetLanguageCode">目標語言類型代碼,如:en、zh-CN、zh-TW、ru等</param>
        /// <returns>翻譯結果</returns>
        string Translate(string sourceText, string sourceLanguageCode, string targetLanguageCode);

        /// <summary>
        /// 翻譯文本[自動檢測源語言類型]
        /// ZhangQingFeng    2012-7-27    add
        /// </summary>
        /// <param name="sourceText">源文本</param>
        /// <param name="targetLanguageCode">目標語言類型代碼,如:en、zh-CN、zh-TW、ru等</param>
        /// <returns>翻譯結果</returns>
        string Translate(string sourceText, string targetLanguageCode);
    }
    
}

 

2). Google Post 請求方式翻譯者實現類 

View Code
using System;
using System.Web;
using System.Net;
using System.Text.RegularExpressions;
using System.Text;

namespace Common.Translator
{
    /// <summary>
    /// google translate翻譯者類[非API,URL訪問Google的方式]
    /// ZhangQingFeng    2012-7-27    add
    /// </summary>
    public class GoogleTranslator : ITranslator
    {

        //private string UrlTemplate = "http://translate.google.com.hk/?langpair={0}&text={1}";    //google翻譯URL模板:GET方式請求
        private string UrlTemplate = "http://translate.google.com.hk/";                            //google翻譯URL模板:POST方式請求

        #region 常用語言編碼
        private string AutoDetectLanguage = "auto"; //google自動判斷來源語系
        #endregion

        /// <summary>
        /// 翻譯文本[自動檢測源語言類型]
        /// ZhangQingFeng    2012-7-27    add
        /// </summary>
        /// <param name="sourceText">源文本</param>
        /// <param name="targetLanguageCode">目標語言類型代碼,如:en、zh-CN、zh-TW、ru等</param>
        /// <returns>翻譯結果</returns>
        public string Translate(string sourceText, string targetLanguageCode)
        {
            return Translate(sourceText, AutoDetectLanguage, targetLanguageCode);
        }

        /// <summary>
        /// 翻譯文本
        /// ZhangQingFeng    2012-7-27    add
        /// </summary>
        /// <param name="sourceText">源文本</param>
        /// <param name="sourceLanguageCode">源語言類型代碼,如:en、zh-CN、zh-TW、ru等</param>
        /// <param name="targetLanguageCode">目標語言類型代碼,如:en、zh-CN、zh-TW、ru等</param>
        /// <returns>翻譯結果</returns>
        public string Translate(string sourceText, string sourceLanguageCode, string targetLanguageCode)
        {
            if (string.IsNullOrEmpty(sourceText) || Regex.IsMatch(sourceText, @"^\s*$"))
            {
                return sourceText;
            }

            string strReturn = string.Empty;

            #region POST方式實現,無長度限制
            string url = UrlTemplate;

            //組織請求的數據
            string postData = string.Format("langpair={0}&text={1}", HttpUtility.UrlEncode(sourceLanguageCode + "|" + targetLanguageCode), HttpUtility.UrlEncode(sourceText));
            byte[] bytes = Encoding.UTF8.GetBytes(postData);

            WebClient client = new WebClient();
            client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
            client.Headers.Add("ContentLength", postData.Length.ToString());
            byte[] responseData = client.UploadData(url, "POST", bytes);
            string strResult = Encoding.UTF8.GetString(responseData);    //響應結果 
            #endregion

            #region GET方式實現,有長度限制
            //string url = string.Format(UrlTemplate, HttpUtility.UrlEncode(sourceLanguageCode + "|" + targetLanguageCode), HttpUtility.UrlEncode(sourceText));
            //WebClient wc = new WebClient();
            //wc.Encoding = Encoding.UTF8;
            //string strResult = wc.DownloadString(url);                //響應結果            
            #endregion
                        
            //使用的正則表達式:    \s+id="?result_box"?\s+[^>]*>(.+)</span>\s*</div>\s*</div>\s*<div id=spell-place-holder\s+
            string strReg = @"\s+id=""?result_box""?\s+[^>]*>(.+)</span>\s*</div>\s*</div>\s*<div id=spell-place-holder\s+";
            Match match = Regex.Match(strResult, strReg, RegexOptions.IgnoreCase | RegexOptions.Singleline);

            if (match.Success)
            {
                strReturn = match.Groups[1].Value;
                //<br/>替換為換行,如為HTML翻譯選項則可去除下行代碼
                strReturn = Regex.Replace(strReturn, @"<br\s*/?>", "\n", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                strReturn = Regex.Replace(strReturn, @"<[^>]*>", "", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                strReturn = HttpUtility.HtmlDecode(strReturn);
                
            }
            return strReturn;
        }
    } 
}

 

3). 假模假樣的工廠類……大家勿噴啊,只是一個簡單工廠實現

View Code
using System;

namespace Common.Translator
{
    /// <summary>
    ///    翻譯者工廠類
    /// </summary>
    public class TranslatorFactory
    {
        /// <summary>
        /// 翻譯者
        /// </summary>
        /// <param name="type">翻譯者類型,目前只有提供Google翻譯</param>
        /// <returns>翻譯者對象</returns>
        public static ITranslator CreateTranslator(string type)
        {
            ITranslator translator = null;
            switch (type)
            {
                case "Microsoft":
                    break;
                case "Youdao":
                    break;
                default:
                    translator = new GoogleTranslator();
                    break;
            }

            return translator;
        }
    }
    
}

 

4). 測試類:

View Code
using System;
using System.Collections.Generic;
using Common.Translator;

namespace ConsoleTest
{
    class Program
    {
        static void Main(string[] args)
        {
            ITranslator translator = TranslatorFactory.CreateTranslator("Google");            

            List<string> lst = new List<string>();
            lst.Add("Soft Leather Case for Apple iPad 1 /2/3  With Ploybag Package");
            lst.Add("Soft Leather Case,Case for Apple iPad ,ipad case ,PU case");
            lst.Add("1X ipad leather case");
            lst.Add("Slim enough to slip into a backpack, bag or briefcase, tough enough to protect your iPad from whatever it may find in there. Slip your iPad into Elan Sleeve then flip the tab closure down to secure it. Then gently pull the tab to slide your iPad out quickly and safely. Stain-resistant synthetic outer shell with smooth micro suede interior.");
            lst.Add(@"<p><span><span><span><span>Fit for apple iPad 1/2 /3 leather case</span></span></span></span></p>
<p><span><span><span><span>PU leather material with top quality</span></span></span></span></p>
<p><span><span><span><span>Three bright colors to meet your demand</span></span></span></span></p>
<p><span><span>Durable and waterproof,practical and favorable</span></span></p>
<p><span><span>Protect your tablet from scratches, damage and dirt</span></span></p>
<p><span><span>Unique design allows easy to controls &amp;ports</span><span>&nbsp;<br /><img src=""http://www.xxxx.com/images/Insert/2012/4/19/2012041905405116.JPG"" alt="""" width=""500"" height=""500"" /><br /><img src=""http://www.xxxx.com/images/Insert/2012/4/19/2012041905421548.JPG"" alt="""" width=""500"" height=""500"" /><br /><img src=""http://www.xxxx.com/images/Insert/2012/4/19/2012041905421714.JPG"" alt="""" width=""500"" height=""500"" /><br /><img src=""http://www.xxxx.com/images/Insert/2012/4/19/2012041905420649.JPG"" alt="""" width=""500"" height=""500"" /><br /><img src=""http://www.xxxx.com/images/Insert/2012/4/19/2012041905415831.JPG"" alt="""" width=""500"" height=""500"" /><br /><img src=""http://www.xxxx.com/images/Insert/2012/4/19/2012041905415058.JPG"" alt="""" width=""500"" height=""500"" /></span></span></p>");

            string strSource=string.Join("\n",lst.ToArray());
            string str = translator.Translate(strSource, "zh-CN");
            Console.WriteLine(str);
            Console.WriteLine("完成");
        }
    }
}

 

5). 最后獻上運行結果:

 

PS:此方式的翻譯結果來源於Google翻譯頁面,與那個基本一致,但是其對HTML的判斷力遠遠比不上GoogleAPI,所以大家不要見怪,或許以后小弟有時間了可以把它完善下,各位大俠有需求的也可以自己拿到源代碼改下,嘿嘿。

 

2. 附贈大家Google網站翻譯器的使用方法:

1). 代碼

View Code
using System;
/// <summary>
///    網站翻譯器[Google提供,整頁翻譯器]
///    ZhangQingFeng    2012-7-27    add
///    說明:
///        如果需要在頁面上使用google語言翻譯,需要做以下兩步:
///        1.將本類中的GoogleTranslateMeta內容放入Head中,如:Response.Write(SiteTranslator.GoogleTranslateMeta);
///        2.將本類中的GoogleTranslateControl內容放入頁面中需要顯示“選擇語言”的地方
/// </summary>
public class SiteTranslator
{
    public SiteTranslator()
    {
    }

    /// <summary>
    /// Google整頁翻譯Meta標簽,放入Head部位
    /// </summary>
    public const string GoogleTranslateMeta = @"<meta name=""google-translate-customization"" content=""d83361947aca6bed-626a88e71258e3a8-g3d7ae31013d34b9c-e""></meta>";

    /// <summary>
    /// Google整頁翻譯控件,放入需要顯示“選擇語言”框的地方
    /// </summary>
    public const string GoogleTranslateControl = @"<div id=""google_translate_element""></div><script type=""text/javascript"">function googleTranslateElementInit() { new google.translate.TranslateElement({pageLanguage: 'zh-CN', layout: google.translate.TranslateElement.InlineLayout.SIMPLE, autoDisplay: false}, 'google_translate_element');}</script><script type=""text/javascript"" src=""//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit""></script>";
}

 

2). 使用示例,只要將那兩個變量分別加在HTML頁面的Head中和想出現“選擇語言”框的地方即可。

 

PS:這是小弟第一次寫博,園子里很多大鳥,在各位面前獻丑了,寫出來只是希望大家碰到此類的問題的時候不用再去重復造輪子了,把小弟的輪子改改,或許比那些API更好用。更關鍵的是:無限制,免費,你懂的。^_^

如果代碼對大家有用,還希望大家支持一下。另外,不知道在園子里怎么上傳壓縮包附件,只能發外鏈地址了,希望各位老鳥指點一下啊。

代碼打包下載地址:http://www.kuaipan.cn/file/id_18864681775007923.htm


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM