urllib2 读取为 Unicode

46 投票
2 回答
63327 浏览
提问于 2025-04-15 12:23

我需要存储一个网站的内容,这个网站的内容可能是任何语言的。而且我还需要能够搜索这些内容中的Unicode字符串。

我尝试过一些方法,比如:

import urllib2

req = urllib2.urlopen('http://lenta.ru')
content = req.read()

这些内容是以字节流的形式存在的,所以我可以在里面搜索Unicode字符串。

我需要一种方法,当我使用urlopen并读取内容时,能够根据头部信息中的字符集来解码这些内容,并把它们转换成UTF-8格式。

2 个回答

10

要解析 Content-Type 这个HTTP头信息,你可以使用 cgi.parse_header 这个函数:

import cgi
import urllib2

r = urllib2.urlopen('http://lenta.ru')
_, params = cgi.parse_header(r.headers.get('Content-Type', ''))
encoding = params.get('charset', 'utf-8')
unicode_text = r.read().decode(encoding)

还有一种获取字符集的方法:

>>> import urllib2
>>> r = urllib2.urlopen('http://lenta.ru')
>>> r.headers.getparam('charset')
'utf-8'

或者在Python 3中:

>>> import urllib.request
>>> r = urllib.request.urlopen('http://lenta.ru')
>>> r.headers.get_content_charset()
'utf-8'

字符编码也可以在HTML文档内部指定,比如 <meta charset="utf-8">

100

在你进行的操作之后,你会看到:

>>> req.headers['content-type']
'text/html; charset=windows-1251'

然后:

>>> encoding=req.headers['content-type'].split('charset=')[-1]
>>> ucontent = unicode(content, encoding)

ucontent 现在是一个Unicode字符串(包含140655个字符)——比如说,如果你的终端是UTF-8格式,想要显示其中的一部分:

>>> print ucontent[76:110].encode('utf-8')
<title>Lenta.ru: Главное: </title>

你还可以进行搜索等等。

补充说明:处理Unicode输入输出通常比较麻烦(这可能是最初提问者遇到的问题),不过我会跳过如何在交互式Python解释器中输入Unicode字符串这个复杂的问题(这和最初的问题无关),来展示一旦Unicode字符串正确输入后(我通过字符编码点来做——虽然有点搞笑,但不复杂;-),搜索就非常简单(希望这样能彻底回答最初的问题)。再次假设你使用的是UTF-8终端:

>>> x=u'\u0413\u043b\u0430\u0432\u043d\u043e\u0435'
>>> print x.encode('utf-8')
Главное
>>> x in ucontent
True
>>> ucontent.find(x)
93

注意:请记住,这种方法可能并不适用于所有网站,因为有些网站只在提供的文档中指定字符编码(例如,使用http-equiv元标签)。

撰写回答