2

我目前正在使用以下代码下载 HTML 页面:

Try
    Dim req As System.Net.HttpWebRequest = DirectCast(WebRequest.Create(URL), HttpWebRequest)
    req.Method = "GET"
    Dim resp As Net.HttpWebResponse = DirectCast(req.GetResponse(), Net.HttpWebResponse)
    Dim stIn As IO.StreamReader = New IO.StreamReader(resp.GetResponseStream())
    Dim strResponse As String = stIn.ReadToEnd

    ''Clean up
    stIn.Close()
    stIn.Dispose()
    resp.Close()

    Return strResponse

Catch ex As Exception
    Return ""
End Try

这适用于大多数页面,但对于某些页面(例如:www.gap.com),我得到的响应编码不正确。
例如,在 gap.com 中,我将“'”视为“?”
更不用说如果我尝试加载 google.cn 会发生什么......

我在这里缺少什么,让 .Net 对其进行编码?

我最担心的是,我实际上必须读取 HTML 中指定编码的元标记,然后重新读取(重新编码?)整个流。

任何指针将不胜感激。


更新:

感谢约翰桑德斯的回复,我更接近了。HttpWebResponse.ContentEncoding 属性似乎总是​​空的。但是, HttpWebResponse.CharacterSet 似乎很有用,并且使用此代码,我越来越接近:

Dim resp As Net.HttpWebResponse = DirectCast(req.GetResponse(), Net.HttpWebResponse)
Dim respEncoding As Encoding = Encoding.GetEncoding(resp.CharacterSet)
Dim stIn As IO.StreamReader = New IO.StreamReader(resp.GetResponseStream(), respEncoding)

现在Google.cn 完美的出现了,所有的汉字。
然而,Gap.Com 仍然犯了错误。

对于 Gap.com,HttpWebResponse.CharacterSet 是 ISO-8859-1,我通过 GetEncoding 获得的编码是 {System.Text.Latin1Encoding},它的正文名称中显示“ISO-8859-1”,以及 Content-在指定的 HTML 中键入 META 标记“charset=ISO-8859-1”。

我还在做错什么吗?
还是 GAP 做错了什么?

4

3 回答 3

2

我相信 HttpWebResponse 具有 ContentEncoding 属性。在 StreamReader 的构造函数中使用它。

于 2009-03-12T14:10:10.470 回答
1

Gap 的网站是错误的。具体问题是他们的页面声称使用了 Latin1 (ISO-8859-1) 的编码,而该页面使用的字符 #146 在 ISO-8859-1 中无效。

但是,该字符在 Windows CP-1252 编码(它是 ISO 8859-1 的超集)中有效。在 CP-1252 中,字符代码 #146 用于右引号字符。您将在今天 Gap.com 主页上的文本中的“您会发现小号和小号”中将其视为撇号。

你可以阅读http://en.wikipedia.org/wiki/Windows-1252了解更多详情。事实证明,这种事情是最初以 CP-1252 编码保存内容的网页上的常见问题(例如,从 Word 复制/粘贴)。

故事的寓意:始终将国际化文本作为 Unicode 存储在您的数据库中,并始终在您的 Web 服务器上以 UTF8 格式发出 HTML!

于 2009-08-14T21:07:32.150 回答
0

大牛,有些页面甚至没有返回值CharacterSet,所以这种方法不是那么可靠。有时甚至浏览器都无法“猜测”要使用哪种编码,所以我认为你不能进行 100% 的编码识别。

在我的特殊情况下,当我处理西班牙语或葡萄牙语页面时,我使用UTF7编码,它对我来说工作得很好(áéíóúñÑêã...等)。

可能您可以先加载一个 CharacterSet 代码表及其对应的 Encoding。如果 CharacterSet 为空,您可以提供默认编码。

构造函数中的detectEncodingFromByteOrderMarks参数StreamReader可能会有所帮助,因为它会自动检测或从第一个字节中推断出一些编码。

于 2009-05-19T04:50:46.063 回答