在python 3中处理多个字符集

mag*_*eto 2 python character-encoding python-3.3

我在Windows 8中使用python 3.3.0.

requrl = urllib.request.Request(url) 

response = urllib.request.urlopen(requrl)

source = response.read()

source = source.decode('utf-8')
Run Code Online (Sandbox Code Playgroud)

如果网站有utf-8字符集,它将正常工作但如果它有iso-8859-1或任何其他charset.意味着我可能有不同的网站网址与不同的字符集.那么,如何处理多个字符集?

现在让我告诉你我在努力解决这个问题时的努力,例如:

    b1 = b'charset=iso-8859-1'
    b1 = b1.decode('iso-8859-1')

    if b1 in source:
            source = source.decode('iso-8859-1')
Run Code Online (Sandbox Code Playgroud)

它给了我一个错误,TypeError: Type str doesn't support the buffer API 所以,我假设它正在考虑将b1视为字符串!这不是正确的方法!:(

请不要说在源代码中手动更改字符集或者您是否阅读过python文档!我已经尝试过将我的脑袋放到python 3文档中,但仍然没有运气,或者我可能没有选择正确的模块/内容来阅读!

Fra*_*ila 5

在Python 3中,a str实际上是一系列unicode字符(相当于u'mystring'Python 2中的语法).你得到的response.read()是一个字节串(一个字节序列).

b1 in source失败的原因是你试图在字节字符串中找到一个unicode字符序列.这没有任何意义,所以它失败了.如果取出该行,它应该可以工作,因为您现在正在比较两个字节序列.b1.decode('iso-8859-1')

现在回到你真正的根本问题.要支持多个字符集,您需要确定字符集,以便将其解码为Unicode字符串.这很棘手.通常,您可以检查Content-Type响应的标头.(请参阅下面的规则.)但是,如此多的网站在标题声明了错误的编码,我们必须为html开发其他复杂的编码嗅探规则.请阅读该链接,以便您了解这是一个多么困难的问题!

我推荐你:

  1. 使用请求库而不是urllib,因为它会自动正确处理大多数unicode转换.(它也更容易使用.)如果在此层转换为unicode失败:
  2. 尝试将字节直接传递给您正在使用的基础库(例如lxmlhtml5lib),并让它们处理确定编码.他们经常为文档类型实现正确的charset-sniffing算法.

如果这些都不起作用,你可以更积极地使用像chardet这样的库来检测编码,但根据我的经验,错误地为他们的网页提供服务的人是如此无能,以至于他们生成混合编码文档,所以你最终会得到垃圾字符无论你做什么!

以下是解释content-type标头中声明的字符集的规则.

  1. 没有明确的charset声明:
    1. text/*(例如text/html)是ASCII格式.
    2. application/*(例如application/json,application/xhtml + xml)是utf-8.
  2. 声明了一个明确的字符集:
    1. 如果type是text/html且charset是iso-8859-1,那它实际上是win-1252(== CP1252)
    2. 否则使用宣称的charset.

(请注意,html5规范通过查找优先于 Content-Type标头的UTF8和UTF16字节标记故意违反了w3c规范.请阅读该编码检测算法链接,看看为什么我们不能拥有好东西...)