请求给定资源时的字符编码问题

时间:2012-07-30 17:20:22

标签: encoding http-headers

我正在为用户构建一个抓取工具来发布链接并预览页面内容,我无法弄清楚为什么有时候我会在请求特定资源时获得,即使Facebook好像正好抓了它。我一定错过了什么。

我正在使用HtmlAgilityPack来帮助我解析HTML,并使用默认WebClient来帮助我提出实际请求。这是相关的代码:

using (ExtendedWebClient client = new ExtendedWebClient())
{
    using (Stream stream = client.OpenRead(endpoint))
    {
        if (stream != null)
        {
            Encoding encoding = GetHttpResponseEncoding(client.ResponseHeaders);
            HtmlDocument document = new HtmlDocument();
            document.Load(stream, encoding);
            return document.DeEntitize();
        }
    }
}

private Encoding GetHttpResponseEncoding(WebHeaderCollection headers)
{
    Encoding encoding = Encoding.UTF8; // use UTF-8 by default.
    string contentType = headers.Get("Content-Type");
    if (contentType != null) // expected form: "text/html; charset=utf-8".
    {
        string[] keyValuePairs = contentType.Split(';');
        foreach (string[] kvp in keyValuePairs.Select(kvp => kvp.Split('=')))
        {
            if (kvp.Length == 2 && kvp[0].Trim().ToLowerInvariant() == "charset")
            {
                // use the response header encoding.
                return Encoding.GetEncoding(kvp[1]);
            }
        }
    }
    return encoding;
}

public static HtmlDocument DeEntitize(this HtmlDocument document)
{
    string html = HtmlEntity.DeEntitize(document.DocumentNode.OuterHtml);
    HtmlDocument decoded = new HtmlDocument();
    decoded.LoadHtml(html);
    return decoded;
}

ExtendedWebClient只是通过添加模拟Firefox浏览器请求的System.Net.WebClient标头来扩展UserAgent

测试代码使用以下端点参数调用第一段代码:

new Uri("http://www.cronica.com.ar/diario/2012/07/30/30541-delpo-quiere-meterse-en-la-tercera-ronda.html")

以下是该页面的一小段代码:

  

JuanMart nDelPotro,que viene de vencerc modamenteal croata Ivan Dodig

即使在浏览器窗口中打开该链接(并查看来源),我也会感到愤怒

让我疯狂的是 Facebook能够正确阅读。那么这里有什么问题,他们是说他们的编码是UTF-8但实际上并不符合那个标准,或我在图片中遗漏了什么

请注意,使用此代码,我能够正确解析Facebook的西班牙语主页,其中包含ñ这样的字符,这可能会在遇到编码问题时出现问题,但这是其他内容< / em>的

1 个答案:

答案 0 :(得分:0)

我认为你的解析器工作正常。只是页面 A)使用混合/不正确的编码或 B)实际上是在编写unicode替换字符' ',即字符在某处被释放之前输出到页面(如进/出数据库)。在正确显示重音的地方,页面使用的是html实体,而不是字符本身。

如果 A)您可以尝试检测编码(痛苦,有问题)。

如果 B)您无法做任何事情。