2017-04-18 117 views
0

我正在阅读使用HtmlAgilityPack的几个网站的元描述。C#解码非ASCII字符?

我注意到如果它不是英文字母,它不会解码特殊字符。 (如日本信件)。

我正在使用编码UTF8 - 我应该使用别的东西。

byte[] bytes = Encoding.Default.GetBytes(item.Attributes["content"].Value); 
return Encoding.UTF8.GetString(bytes); 
+2

为什么你使用'Encoding.Default'呢?此外,你为什么不只是做'return item.Attributes [“content”]。Value;'? –

+0

如果我只是返回item.Attributes [“content”] .value;那么它显示不是日文字母。显示的内容如下: v ̌ R 〜 @ScottChamberlain – Ben

+0

你是如何显示它的?显示该代码。同时检查'Value'返回的'string'对象,通过检查调试器中的字符串来查看它是否具有正确的值。如果它没有正确的值,则需要进一步回顾并找出为什么'item'不解析数据源是否正确。 –

回答

0

根据您的评论,似乎您的网站使用的是SHIFT-JIS编码,而不是UTF-8。我已经为UTF-8和SHIFT-JIS添加了两个样本。

 using (var client = new WebClient()) 
     { 
      // UTF-8 
      var content = client.DownloadString("http://www3.nhk.or.jp/news/"); 
      var doc = new HtmlDocument(); 
      doc.LoadHtml(content); 
      var metaDescNode = doc.DocumentNode.SelectSingleNode("//meta[@name=\"description\"]"); 
      var bytes = Encoding.Default.GetBytes(metaDescNode.Attributes["content"].Value); 
      var decodedMetaDesc = Encoding.UTF8.GetString(bytes); // This string has decoded characters 

      // Shift_JIS 
      var japaneseEncoding = Encoding.GetEncoding(932); 
      var content2 = client.DownloadString("http://www.toronto-electricians.com/"); 
      var doc2 = new HtmlDocument(); 
      doc2.LoadHtml(content2); 
      var metaDescNode2 = doc2.DocumentNode.SelectSingleNode("//meta[@name=\"description\"]"); 
      var bytes2 = Encoding.Default.GetBytes(metaDescNode2.Attributes["content"].Value); 
      var decodedMetaDesc2 = japaneseEncoding.GetString(bytes2); // This string has decoded characters 
     } 

截图#1来自调试器。

enter image description here

截图#2从调试器。

enter image description here

+0

你的代码确实可以和你在样本中使用的网站一起工作。我曾尝试使用不同的网站'http:// www。toronto-electricians.com/'并显示 v ̌ R 〜 。你可以用我的网站运行你的代码吗?它显示对你好吗? – Ben

+0

啊!您的网站使用“Shift_JIS”字符集,让我更新我的代码。 – Ignas

+0

@Ben查看更新的代码。 – Ignas

1

WebClient.DownloadString是有限的,高水平的方法,该方法使得它笨拙且容易出错做根本上简单的事情。

通过HTTP获取网页很简单。你给一个URL和一些请求标题;服务器响应一些响应头文件和一个字节流。响应标题通常表示文本正文的字符编码。如果不是,文本正文可能会说出来。 HTMLAgilityPack理解这一点,并提供HtmlWeb类来从该交互中创建HtmlAgilityPack.HtmlDocument。

var document = new HtmlWeb().Load("http://www3.nhk.or.jp/news/"); 
var keywords = document.DocumentNode 
    .SelectSingleNode("//meta[@name='keywords']") 
    .Attributes["content"]?.Value; 
Console.WriteLine(keywords); 
Console.WriteLine([email protected]" 
    StreamEncoding: {document.StreamEncoding?.EncodingName} 
    DeclaredEncoding: {document.DeclaredEncoding?.EncodingName} 
    Encoding:   {document.Encoding?.EncodingName}"); 

NHK,ニュース,NHK NEWS WEB 

    StreamEncoding: Unicode (UTF-8) 
    DeclaredEncoding: 
    Encoding:   Unicode (UTF-8) 
+0

我已经尝试使用URL运行你的代码:'http:// www.toronto-electricians.com /'SHIFT-JIS编码,它不工作,返回 ̉ グ – Ben

+0

@Ben我很难过目前来说。我确实通过[W3C验证程序](https://validator.w3.org/check?uri=http%3A%2F%2Fwww.toronto-electricians.com%2F&charset=%28detect+automatically%29&fbc=1&doctype = Inline&fbd = 1&group = 1&ss = 1&outline = 1&No200 = 1&verbose = 1)并且它在XHTML中失败。但是没有任何东西会跳出来让HtmlAgilityPack破坏角色。 –

+0

@Ben,很难解析分层规范,但是你的服务器发送一个没有字符集声明的HTTP Content-Type头。带有charset声明的HTTP Content-Type头文件肯定会覆盖任何HTML/XHTML元字符集声明。在头文件存在但charset不存在的情况下,也许重写会使用默认的UTF-8进行。您可以更改服务器以将字符集包含在Content-Type标头中吗? –