【问题标题】:What is the default content-type/charset?默认的内容类型/字符集是什么?
【发布时间】:2010-12-20 23:35:00
【问题描述】:

根据这个答案:urllib2 read to Unicode

我必须获取内容类型才能更改为 Unicode。但是,有些网站没有“字符集”。

例如,this 页面的 ['content-type'] 是“text/html”。我无法将其转换为 Unicode。

encoding=urlResponse.headers['content-type'].split('charset=')[-1]
htmlSource = unicode(htmlSource, encoding)
TypeError: 'int' object is not callable

是否有默认的“编码”(当然是英文)...如果没有找到,我可以使用它吗?

【问题讨论】:

  • 我已经更新了我的评论,如果你喜欢一直使用一个解码功能。
  • AAARRRGGHHH 检查网址,它确实有一个字符集;阅读错误信息,代码隐藏了 unicode() 函数 FFS
  • 嘿!我们都没有发现它!
  • @bobince:是的,所以需要一个“我错了”按钮,这样你就可以放弃你的不义之分,但把你的答案留在那里——当然是适当的标签 :-)

标签: python html unicode encoding


【解决方案1】:

好吧,我刚刚浏览了给定的 URL,它重定向到

http://www.engadget.com/2009/11/23/apple-hits-back-at-verizon-in-new-iphone-ads-video

然后在 Firefox 中点击 Ctrl + U (查看源代码),它会显示

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

@Konrad:“似乎……使用 ISO-8859-1”是什么意思??

@alex:是什么让你认为它没有“字符集”??

查看您拥有的代码(我们猜测是导致错误的行(请始终显示完整回溯和错误消息!)):

htmlSource = unicode(htmlSource, encoding)

以及错误信息:

TypeError: 'int' object is not callable

这意味着unicode 不是指内置函数,而是指int。我记得在您的另一个问题中,您有类似

if unicode == 1:

我建议您为该变量使用其他名称——比如 use_unicode。

更多建议:(1) 始终显示足够的代码来重现错误 (2) 始终阅读错误消息。

【讨论】:

  • +1 不错的发现,我没有意识到他覆盖了内置的 unicode 函数
【解决方案2】:

如果没有明确的内容类型,它应该是 ISO-8859-1,如答案中所述。不幸的是,情况并非总是如此,这就是为什么浏览器开发人员花费一些时间来让算法尝试根据您的页面内容猜测内容类型。

幸运的是,Mark Pilgrimchardet module 的形式为将 Firefox 实现移植到 Python 做了所有艰苦的工作。 Dive Into Python 3 的其中一章的introduction on how it works 也很值得一读。

【讨论】:

    【解决方案3】:

    htmlSource=htmlSource.decode("utf8") 应该适用于大多数情况,除非您正在抓取非英语编码网站。

    或者你可以这样写强制解码函数:

    def forcedecode(text):
        for x in ["utf8","sjis","cp1252","utf16"]:
            try:return text.decode(x)
            except:pass
        return "Unknown Encoding"
    

    【讨论】:

    • cp1252utf16 将成功解码 any 字节序列,因此其中一个必须在最后进行。 (我建议cp1252;UTF-16 并未在网络上广泛使用,因为存在浏览器问题并且通常效率低下。)
    • 谢谢,我把它移到了最后。是的,utf16 并没有被广泛使用,但在我的语言中,utf8 占用 3 个字节,但 utf16 占用 2 个字节,我们只将它用于通常的文本或 csv 文件,而且 microsoft excel 不适合 utf8 编码的 csv 文件。
    • @bobince:很抱歉,您的第一句话不正确。您可能正在考虑具有该属性的 ISO-8859-1 aka latin1(与定义所有代码点的任何其他单字节套件一样)。 cp1252 没有定义 5 个字节的值,例如'\x81'。 UTF-16 将在单独的低代理项上失败,并且在高代理项上没有低代理项。
    • 谢谢约翰,这是有道理的,utf16 可能从 0-FFFF 开始工作,将它移到结尾,但我想到的只有一件事,这种编码“\xff\xff\81”是什么?刚刚制作了一个?
    • @S.Mark:“工作”并不意味着“没有引发异常”。如果您要询问该 3 字节序列的哪种编码是有效的,答案显然是 ISO-8859-1(或定义了所有点的任何其他编码);如果您添加顺序必须实用且有意义的骑手,则将切断 ISO-8859-1,因为 \x80 到 \x9f 都包括在内都是无用的控制字符。为什么要问?
    【解决方案4】:

    是否有默认的“编码”(当然是英文)...如果没有找到,我可以使用它吗?

    不,没有。你必须猜。

    简单的方法:尝试解码为UTF-8。如果它有效,那就太好了,它可能是 UTF-8。如果不是,请为您正在浏览的页面类型选择最有可能的编码。对于cp1252 的英文页面,Windows 西欧编码。 (类似于 ISO-8859-1;事实上,即使您指定了该字符集,大多数浏览器也会使用 cp1252 而不是 iso-8859-1,因此值得复制该行为。)

    如果您需要猜测其他语言,它会变得非常棘手。现有的模块可以帮助您在这些情况下进行猜测。参见例如。 chardet.

    【讨论】:

    • 我可以这样做:htmlSource = htmlSource.decode('utf8')...对于所有内容?
    • http 有一个默认编码,参见 RFC w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7.1
    • AAARRRGGHHH 检查网址,它确实有一个字符集;阅读错误信息,代码隐藏了 unicode() 函数 FFS
    • 默认字符集是 ISO-8859-1。请参阅 RFC2616,第 3.7.1 和 3.4.1 节
    • RFC 7231 废弃了旧的 ISO-8859-1 默认值。 tools.ietf.org/html/rfc7231#appendix-B
    猜你喜欢
    • 2011-01-04
    • 2023-04-09
    • 2019-02-07
    • 1970-01-01
    • 2014-07-28
    • 2011-05-04
    • 1970-01-01
    • 2012-12-29
    • 1970-01-01
    相关资源
    最近更新 更多