【问题标题】:urllib2 read to Unicodeurllib2 读取到 Unicode
【发布时间】:2010-11-04 11:42:37
【问题描述】:

我需要存储可以使用任何语言的网站内容。而且我需要能够在内容中搜索 Unicode 字符串。

我尝试过类似的方法:

import urllib2

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

内容是字节流,所以我可以搜索它以查找 Unicode 字符串。

我需要一些方法,当我执行 urlopen 然后读取时使用标题中的字符集来解码内容并将其编码为 UTF-8。

【问题讨论】:

标签: python unicode urllib2


【解决方案1】:

在您执行的操作之后,您会看到:

>>> 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 I/O 通常很棘手(这可能是阻碍原始提问者的原因)但我将绕过将 Unicode 字符串输入到交互式 Python 解释器的难题(与原始问题完全无关)展示如何正确输入 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 元标记)。

【讨论】:

  • 嗨,亚历克斯,感谢您的回复。但是如果我这样做: ucontent 中的 u'Главное' 它会返回 False。有没有更好的搜索方式?
  • 你是如何输入那个 u'...' 字符串的? Unicode I/O 很棘手,因为您的终端和 Python 必须在相同的波长上。使用明确的 Unicode 代码点(无聊但不棘手)工作正常,让我编辑我的答案以显示这一点。
  • 我正在使用控制台输入,如果我需要为单元测试执行此操作,我应该将编码设置为:文件顶部?
  • 完全取决于你的终端/控制台的编码是如何设置的!见python.org/dev/peps/pep-0263——例如对于 utf-8,使用注释 # -- coding: utf-8 -- at file start.
  • 在响应头上使用.split来提取charset参数是作弊。如果分号后面还有一个参数怎么办?
【解决方案2】:

要解析Content-Type http header,你可以使用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 文档中指定字符编码,例如,&lt;meta charset="utf-8"&gt;

【讨论】:

    猜你喜欢
    • 2015-09-19
    • 1970-01-01
    • 1970-01-01
    • 2014-02-25
    • 2012-11-24
    • 1970-01-01
    • 1970-01-01
    • 2010-11-14
    • 2011-05-16
    相关资源
    最近更新 更多