python - 使用 lxml HTML 解析 UTF-8/unicode 字符串

标签 python parsing unicode utf-8 lxml

我一直在尝试使用 etree.HTML() 解析编码为 UTF-8 的文本,但没有成功。

→ python
Python 2.7.1 (r271:86832, Jun 16 2011, 16:59:05) 
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from lxml import etree
>>> import requests
>>> headers = {'User-Agent': "Opera/9.80 (Macintosh; Intel Mac OS X 10.8.0) Presto/2.12.363 Version/12.50"}
>>> r = requests.get("http://www.rakuten.co.jp/", headers=headers)
>>> r.status_code
200
>>> r.headers
{'x-cache': 'MISS from www.rakuten.co.jp', 'transfer-encoding': 'chunked', 'set-cookie': 'wPzd=lng%3DNA%3Acnt%3DCA; expires=Tue, 13-Aug-2013 16:51:38 GMT; path=/; domain=www.rakuten.co.jp', 'server': 'Apache', 'pragma': 'no-cache', 'cache-control': 'private', 'date': 'Mon, 13 Aug 2012 16:51:38 GMT', 'content-type': 'text/html; charset=EUC-JP'}
>>> responsetext = r.text

到目前为止一切顺利。响应文本很好,它是一个 unicode 字符串。现在,如果我想获取 CSS URI 列表。也没有问题。

>>> tree = etree.HTML(responsetext)
>>> csspathlist = tree.xpath('//link[@rel="stylesheet"]/@href')
>>> csspathlist
['http://a.ichiba.jp.rakuten-static.com/com/inc/home/20080930/opt/css/normal/common.css?v=1207111500', 'http://a.ichiba.jp.rakuten-static.com/com/inc/home/20080930/opt/css/normal/layout.css?v=1207111500', 'http://a.ichiba.jp.rakuten-static.com/com/inc/home/20080930/opt/css/normal/sidecolumn.css?v=1207111500', 'http://a.ichiba.jp.rakuten-static.com/com/inc/home/20080930/beta/css/liquid/api.css?v=1207111500', '/com/inc/home/20080930/beta/css/liquid/myrakuten_dpgs.css', 'http://a.ichiba.jp.rakuten-static.com/com/inc/home/20080930/opt/css/normal/leftcolumn.css?v=1207111500', 'http://a.ichiba.jp.rakuten-static.com/com/inc/home/20080930/opt/css/normal/header.css?v=1207111500', '/com/inc/home/20080930/opt/css/normal/footer.css', 'http://a.ichiba.jp.rakuten-static.com/com/inc/home/20080930/beta/css/liquid/ipad.css', 'http://a.ichiba.jp.rakuten-static.com/com/inc/home/20080930/opt/css/normal/genre.css?v=1207111500', 'http://a.ichiba.jp.rakuten-static.com/com/inc/home/20080930/opt/css/normal/supersale.css?v=1207111500', '/com/inc/home/20080930/beta/css/liquid/rakuten_membership.css', 'http://a.ichiba.jp.rakuten-static.com/com/inc/home/20080930/beta/css/noscript/set.css?v=1207111500', 'http://a.ichiba.jp.rakuten-static.com/com/inc/home/20080930/beta/css/liquid/suggest-2.0.1.css?v=1204231500', 'http://a.ichiba.jp.rakuten-static.com/com/inc/home/20080930/beta/css/liquid/liquid_banner.css?v=1203011138', 'http://a.ichiba.jp.rakuten-static.com/com/inc/home/20080930/beta/css/liquid/area_announce.css?v=1203011138']

现在让我们从 unicode 更改为 UTF-8 并再次请求 CSS URI 列表。

>>> htmltext = responsetext.encode('utf-8')
>>> tree2 = etree.HTML(htmltext)
>>> csspathlist2 = tree2.xpath('//link[@rel="stylesheet"]/@href')
>>> csspathlist2
[]

我得到一个空列表。

>>> etree.tostring(tree2)
'<html lang="ja" xmlns="http://www.w3.org/1999/xhtml" xmlns:og="http://ogp.me/ns#" xmlns:fb="http://www.facebook.com/2008/fbml"><head><meta http-equiv="Content-Type" content="text/html; charset=EUC-JP"/><meta http-equiv="Content-Style-Type" content="text/css"/><meta http-equiv="Content-Script-Type" content="text/javascript"/><title/></head></html>'

确实,第二次解析在标题中的第一个日文字符之后立即停止。

<meta http-equiv="Content-Script-Type" content="text/javascript"/>
<title> 【楽天市場】Shopping is Entertainment! : インターネット最大級の通信販売、通販オンラインショッピングコミュニティ </title>

我仍在努力了解我做错了什么。

最佳答案

好的,刚刚找到。在 StackOverflow 上写问题通常很有帮助。

etree.HTML() 正在尝试根据文档中的 meta 猜测编码

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

在这种情况下,我手动将文档转换为 utf-8,这意味着它不再是日文编码:EUC-JP。所以解决这个问题只需要强制HTML解析器理解utf-8。在我们的例子中,代码变为:

>>> myparser = etree.HTMLParser(encoding="utf-8")
>>> tree = etree.HTML(htmltext, parser=myparser)

关于python - 使用 lxml HTML 解析 UTF-8/unicode 字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11938924/

相关文章:

c# - 在 C# 中解析 PowerShell 输出

python - 如何加快读取多个文件并将数据放入数据框中?

javascript - 重构 JSON 数据

Mysql 格鲁吉亚语 Unicode

vim - vim 或其他地方文件编码和编码的基本原理

python - 在多线程中使用锁

python - 运行斐波那契数列的奇怪输出

python - 如何使用 Python 以可迭代的方式映射 JSON 值

language-agnostic -\r\n 作为 UTF8 字符的一部分?

python - 将 str 分数转换为 pandas df 中的 float