获取网页字符集的简便可靠方法是什么?

14 投票
4 回答
6357 浏览
提问于 2025-04-16 08:54

我有点惊讶,用Python获取网页的字符集竟然这么复杂。我是不是漏掉了什么方法?HTTPMessage有很多功能,但就是没有这个。

>>> google = urllib2.urlopen('http://www.google.com/')
>>> google.headers.gettype()
'text/html'
>>> google.headers.getencoding()
'7bit'
>>> google.headers.getcharset()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: HTTPMessage instance has no attribute 'getcharset'

所以你得先获取头部信息,然后把它分开,分两次。

>>> google = urllib2.urlopen('http://www.google.com/')
>>> charset = 'ISO-8859-1'
>>> contenttype = google.headers.getheader('Content-Type', '')
>>> if ';' in contenttype:
...     charset = contenttype.split(';')[1].split('=')[1]
>>> charset
'ISO-8859-1'

为了这么基本的功能,步骤居然这么多,难道我真的漏掉了什么吗?

4 个回答

0

你并没有漏掉什么。它正在做正确的事情——HTTP响应的编码是内容类型的一部分。

另外,有些网页可能只发送 Content-Type: text/html,然后通过 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 来设置编码——不过这是一种不太好的做法(网页作者的锅),而且并不常见。

5

我做了一些研究,找到了这个解决方案:

response = urllib.request.urlopen(url)
encoding = response.headers.get_content_charset()

这是我在Python 3中会这样做的。我没有在Python 2中测试过,但我猜你需要用urllib2.request来代替urllib.request

下面是它的工作原理,因为官方的Python文档没有解释得很好:urlopen的结果是一个http.client.HTTPResponse对象。这个对象的headers属性是一个http.client.HTTPMessage对象。根据文档,它“是使用email.message.Message类实现的”,这个类有一个叫做get_content_charset的方法,它会尝试确定并返回响应的字符集。

默认情况下,如果无法确定字符集,这个方法会返回None,但你可以通过传递一个failobj参数来改变这个行为:

encoding = response.headers.get_content_charset(failobj="utf-8")

撰写回答