2

C# を使用して Microsoft Translator API (SOAP) で Web ページを翻訳します。ウェブサイトを翻訳したいのですが、翻訳済みページをクロールするためにも Google が必要なため、Translator Widget の使用は適切ではありません。そのため、ブラウザに送信する前に翻訳する必要があります。

これまでのところ、URL を渡すだけでhttp://www. microsofttranslator.com/bv.aspx?from=&to=nl&a=http%3A%2F%2Fwww.imdb.com%2F

これまでに行った試みは次のとおりです。 1. Url から文字列をダウンロードし、Client.Translate(..) に渡します。

メッセージを逆シリアル化しようとしているときに、フォーマッタが例外をスローしました: 操作 'Translate' の要求メッセージの本文を逆シリアル化中にエラーが発生しました。XML データの読み取り中に、文字列コンテンツの最大長クォータ (30720) を超えました。このクォータは、XML リーダーの作成時に使用される XmlDictionaryReaderQuotas オブジェクトの MaxStringContentLength プロパティを変更することで増やすことができます。行 516、位置 48。

2.

private static void processDocument(HtmlAgilityPack.HtmlDocument html, LanguageServiceClient Client)
        {
            HtmlNodeCollection coll = html.DocumentNode.SelectNodes("//text()[normalize-space(.) != '']");
            foreach (HtmlNode node in coll)
            {
                if (node.InnerText == node.InnerHtml)
                {
                    //node.InnerHtml = translateText(node.InnerText);
                    node.InnerHtml = Client.Translate("", node.InnerText, "en", "fr", "text/html", "general");
                }
            }

        }

これは時間がかかりすぎます。そして最後に、Bad request (400) 例外が発生します。

この問題に取り組む最善の方法は何でしょうか? また、毎回翻訳しなくても済むように、ドキュメントを保存する予定です。

4

1 に答える 1

1

この C# の例では、HTML をローカル ファイルから変換します。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using HtmlAgilityPack;

namespace TranslationAssistant.Business
{
class HTMLTranslationManager
{
    public static int DoTranslation(string htmlfilename, string fromlanguage, string tolanguage)
    {
        string htmldocument = File.ReadAllText(htmlfilename);
        string htmlout = string.Empty;

        HtmlDocument htmlDoc = new HtmlDocument();
        htmlDoc.LoadHtml(htmldocument);
        htmlDoc.DocumentNode.SetAttributeValue("lang", TranslationServices.Core.TranslationServiceFacade.LanguageNameToLanguageCode(tolanguage));
        var title = htmlDoc.DocumentNode.SelectSingleNode("//head//title");
        if (title != null) title.InnerHtml = TranslationServices.Core.TranslationServiceFacade.TranslateString(title.InnerHtml, fromlanguage, tolanguage, "text/html");
        var body = htmlDoc.DocumentNode.SelectSingleNode("//body");
        if (body != null)
        {
            if (body.InnerHtml.Length < 10000)
            {
                body.InnerHtml = TranslationServices.Core.TranslationServiceFacade.TranslateString(body.InnerHtml, fromlanguage, tolanguage, "text/html");
            }
            else
            {
                List<HtmlNode> nodes = new List<HtmlNode>();
                AddNodes(body.FirstChild, ref nodes);

                Parallel.ForEach(nodes, (node) =>
                    {
                        if (node.InnerHtml.Length > 10000)
                        {
                            throw new Exception("Child node with a length of more than 10000 characters encountered.");
                        }
                        node.InnerHtml = TranslationServices.Core.TranslationServiceFacade.TranslateString(node.InnerHtml, fromlanguage, tolanguage, "text/html");
                    });
            }
        }
        htmlDoc.Save(htmlfilename, Encoding.UTF8);
        return 1;
    }

    /// <summary>
    /// Add nodes of size smaller than 10000 characters to the list, and recurse into the bigger ones.
    /// </summary>
    /// <param name="rootnode">The node to start from</param>
    /// <param name="nodes">Reference to the node list</param>
    private static void AddNodes(HtmlNode rootnode, ref List<HtmlNode> nodes)
    {
        string[] DNTList = { "script", "#text", "code", "col", "colgroup", "embed", "em", "#comment", "image", "map", "media", "meta", "source", "xml"};  //DNT - Do Not Translate - these nodes are skipped.
        HtmlNode child = rootnode;
        while (child != rootnode.LastChild)
        {
            if (!DNTList.Contains(child.Name.ToLowerInvariant())) {
                if (child.InnerHtml.Length > 10000)
                {
                    AddNodes(child.FirstChild, ref nodes);
                }
                else
                {
                    if (child.InnerHtml.Trim().Length != 0) nodes.Add(child);
                }
            }
            child = child.NextSibling;
        }
    }

}
}

これは http://github.com/microsofttranslator/documenttranslatorの HTMLTranslationManager.cs であり、TranslationServiceFacade.cs のヘルパー関数 TranslateString() を使用します。単純化して、TranslateString() の代わりに翻訳サービス呼び出しをここに挿入するだけです。

于 2016-07-03T16:15:31.320 に答える