我在 Windows 8 中使用 python 3.3.0。
requrl = urllib.request.Request(url)
response = urllib.request.urlopen(requrl)
source = response.read()
source = source.decode('utf-8')
如果网站有 utf-8
字符集,它会工作正常,但如果它有 iso-8859-1
或任何其他 charset
怎么办.意味着我可能有不同的网站 url 和不同的字符集。
那么,如何处理多个charset呢?
现在让我告诉您我在尝试解决此问题时所做的努力,例如:
b1 = b'charset=iso-8859-1'
b1 = b1.decode('iso-8859-1')
if b1 in source:
source = source.decode('iso-8859-1')
它给了我一个错误,比如 TypeError: Type str doesn't support the buffer API
所以,我假设它将 b1 视为字符串!这不是正确的方法! :(
请不要说在源代码中手动更改字符集,或者您是否阅读过 python 文档! 我已经尝试过深入研究 python 3 文档,但仍然没有运气,或者我可能没有找到正确的模块/内容来阅读!
最佳答案
在 Python 3 中,str
实际上是一个 unicode 字符序列(相当于 Python 2 中的 u'mystring'
语法)。您从 response.read()
得到的是一个字节串(字节序列)。
b1 in source
失败的原因是您试图在字节字符串 中找到unicode 字符序列。这没有意义,所以它失败了。如果您删除行 b1.decode('iso-8859-1')
,它应该可以工作,因为您现在正在比较两个字节序列。
现在回到您真正的根本问题。要支持多个字符集,您需要确定字符集,以便将其解码为 Unicode 字符串。这很难做到。通常,您可以检查响应的 Content-Type
header 。 (请参阅下面的规则。)但是,如此多的网站在 header 中声明了错误的编码,我们不得不开发其他 complicated encoding sniffing rules for html .请阅读该链接,以便您了解这是一个多么困难的问题!
我推荐你:
- 使用requests library 而不是 urllib,因为它会自动正确处理大多数 unicode 转换。 (它也更容易使用。)如果在此层转换为 unicode 失败:
- 尝试将字节直接传递给您正在使用的底层库(例如
lxml
或html5lib
)并让它们处理确定编码。他们经常为文档类型实现正确的字符集嗅探算法。
如果这些都不起作用,您可以更积极地使用像 chardet 这样的库来检测编码,但根据我的经验,那些错误地提供网页服务的人非常无能,以至于他们会生成混合编码的文档,所以无论你做什么,你最终都会得到垃圾字符!
以下是解释 content-type
header 中声明的字符集的规则。
- 没有明确声明的字符集:
- text/*(例如,text/html)采用 ASCII 格式。
- application/*(例如application/json、application/xhtml+xml)是utf-8。
- 使用显式声明的字符集:
- 如果type是text/html,charset是iso-8859-1,实际上是win-1252 (==CP1252)
- 否则使用声明的字符集。
(请注意,html5 规范通过查找 UTF8 和 UTF16 字节标记优先于 Content-Type header 来故意违反 w3c 规范。请阅读编码检测算法链接,看看为什么我们可以有好东西...)
关于python - 在 python 3 中处理多个字符集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13089123/