【问题标题】:Encoding problem with C# utilising HttpWebRequest使用 HttpWebRequest 的 C# 编码问题
【发布时间】:2011-02-21 18:06:52
【问题描述】:

当从 HttpWebRequest 返回字符串时,我收到的字符代码(' 和 &ampquote;)会破坏我的响应(显示 39; 和 uto;):

internal static void TranslateThis(Player player, string fromLang, string toLang, string text){
    try
    {
        string translated = null;
        HttpWebRequest hwr = (HttpWebRequest)HttpWebRequest.Create("http://translate.google.com/?langpair=" + fromLang + "|" + toLang + "&text=" + text.Replace(" ", "+") + "#");
        HttpWebResponse res = (HttpWebResponse)hwr.GetResponse();
        StreamReader sr = new StreamReader(res.GetResponseStream());
        string html = sr.ReadToEnd();
        int a = html.IndexOf("onmouseout=\"this.style.backgroundColor='#fff'\">") + 47;
        int b = html.IndexOf("</span>",html.IndexOf("onmouseout=\"this.style.backgroundColor='#fff'\">") + 47);
        translated = html.Substring(a, b - a);
        if (translated.Length < (10 * text.Length)){
            if (player == Player.Console)
            {
                player.ParseMessage(translated, true);
            }
            else
            {
                player.ParseMessage(translated, false);
            }
        } else {
            player.Message("Usage: /translate [lang] [message]");
        }
    }
    catch
    {
        player.Message("Usage: /translate [lang] [message]");
    }
}

【问题讨论】:

  • 您的示例没有显示实际问题 - 您需要首先确定您的“html”变量是否包含您期望的值,然后使用该值测试您的 ParseMessage 方法。
  • 如果 html 变量包含 ' 或 " 这似乎会给我带来问题。
  • 我已经用 StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF7); 进行了测试一些法语字符现在可以正常显示了。很抱歉没有提供帮助我所需的所有变量。我正在使用谷歌翻译并返回翻译后的字符串。因此它可能在某些法语单词中包含 '(例如 J'ai)。当我向播放器显示消息时,它显示为 J35;ai - 这有助于说明我的问题吗?

标签: c# regex httpwebrequest


【解决方案1】:

首先确保您获得下载内容的正确编码。有关如何执行此操作的代码,请参阅此SO answer

基本上检查 http 标头和元标记的编码,并在必要时重新编码内容。然后执行 HttpUtility.HtmlDecode 以摆脱任何 html 编码字符。现在您已准备好开始搜索您要查找的任何内容。

我还建议使用 Html Agility Pack 之类的东西来解析 html 而不是 indexof。

【讨论】:

  • 如上:使用 3.5 框架,所以不幸的是,我无法使用该方法。我也很抱歉没有早点说明这一点,也感谢您抽出宝贵的时间。
【解决方案2】:

很难说你的 ParseMessage 方法究竟期望什么,所以这只是一个猜测:

您从 Google 翻译获得的结果是 HTML。这意味着如果您想要纯文本输出,则必须将 HTML 转换为文本。您已经成功(至少现在,直到谷歌翻译稍微改变他们的输出页面;您的解决方案并不完全是傻瓜或未来证明)从 HTML 页面中提取翻译。但是翻译是仍然以 HTML 编码的,您需要对其进行解码。为此,您可以使用 WebUtility.HtmlDecode 方法(假设您使用的是 .NET Framework 4):在

之后
translated = html.Substring(a, b - a);

行,添加

translated = WebUtility.HtmlDecode(translated);

【讨论】:

  • 使用 3.5 框架,所以不幸的是,我无法使用该方法。很抱歉没有早点说明,感谢您抽出宝贵时间。
【解决方案3】:

与另一位开发人员的讨论让我在最后一批 cmets 之前尝试这个。以下是最终的工作:

    internal static void TranslateThis(Player player, string fromLang, string toLang, string text){
        try
        {
            string translated = null;
            text = Regex.Replace(text, @"[^\w\.\'\s@-]", "");
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://translate.google.com/?langpair=" + fromLang + "|" + toLang + "&text=" + text.Replace(" ", "+") + "#");

            request.MaximumAutomaticRedirections = 4;
            request.MaximumResponseHeadersLength = 4;

            request.Credentials = CredentialCache.DefaultCredentials;
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            Stream receiveStream = response.GetResponseStream();

            StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF7);
            String html = readStream.ReadToEnd() + "";
            int a = html.IndexOf("onmouseout=\"this.style.backgroundColor='#fff'\">") + 47;
            int b = html.IndexOf("</span>",html.IndexOf("onmouseout=\"this.style.backgroundColor='#fff'\">") + 47);
            translated = html.Substring(a, b - a);
            response.Close();
            readStream.Close();
            if (translated.Length < (10 * text.Length))
            {
                translated = translated.Replace("&#39", "'");
                translated = Regex.Replace(translated, @"[^\w\.\'\s@-]", "");
                if (player == Player.Console)
                {
                    player.ParseMessage(translated, true);
                }
                else
                {
                    player.ParseMessage(translated, false);
                }
            }
            else
            {
                player.Message("Usage: /translate [lang] [message]");
            }
        }
        catch(Exception ex)
        {
            player.Message("Error:" + ex.ToString());

        }
   }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-08
    • 1970-01-01
    • 1970-01-01
    • 2015-02-07
    • 1970-01-01
    • 1970-01-01
    • 2015-11-27
    • 1970-01-01
    相关资源
    最近更新 更多