python - 在 python 3 中处理多个字符集

标签 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')

如果网站有 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 .请阅读该链接,以便您了解这是一个多么困难的问题!

我推荐你:

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

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

以下是解释 content-type header 中声明的字符集的规则。

  1. 没有明确声明的字符集:
    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. 否则使用声明的字符集。

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

关于python - 在 python 3 中处理多个字符集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13089123/

相关文章:

python - 在 Windows 中使用 crypt 模块?

PYTHON 从时间戳算起的分钟数

python - 使用用户代理 header 时 Webscraping CrunchBase 访问被拒绝

python - 在 Python 中混合使用不常见的字符

grid - PySide/QT - 如何将水平或垂直布局添加到网格布局

java - FTP 服务器输出和重音

ios - 如何在 Swift 中打印 Unicode 字符

python - Scrapy - 数据库选择

python - 连接 Pandas 数据帧时整数变成 float

python - 我们可以为 Python 类的不同别名使用不同的 __name__ 属性吗?