【发布时间】:2013-11-24 17:05:37
【问题描述】:
我有以下代码来解析 HTML 网站。这将返回一个 HTML 元素对象。我想在多台机器上运行这段代码,所以当有人试图从代理后面运行它时,实现代理对我来说很重要。
from lxml.html import parse
def parsepage(url):
if proxy:
proxy_support = urllib2.ProxyHandler({"http":proxy})
opener = urllib2.build_opener(proxy_support,urllib2.HTTPHandler)
urllib2.install_opener(opener)
conn = urllib2.urlopen(url)
site = parse(conn).getroot()
else:
site = parse(url).getroot()
return site
在它返回 HTML 元素后,我使用这样的 Xpath 表达式从对象中获取数据:
element = site.xpath(expression)
问题是结果包含非 unicode 数据,其中包含转义字符。例如:
\xe1ci\xf3s 组合
我也尝试过这个实现,但是这个给我一个错误:
def parsepage(url):
if proxy:
proxy_support = urllib2.ProxyHandler({"http":proxy})
opener = urllib2.build_opener(proxy_support,urllib2.HTTPHandler)
urllib2.install_opener(opener)
conn = urllib2.urlopen(url)
rawdata = conn.read()
parser = etree.HTMLParser(encoding="utf-8")
site = etree.HTML(rawdata, parser=parser)
else:
site = parse(url).getroot()
return site
错误信息是:
'utf8' decode 无法解码位置 4 中的字节 0xf3:无效的继续字节
该网站使用 iso-8859-2 字符集。
有没有一种方法可以使用上面列出的解析方法之一将非 unicode 字符转换为 unicode?或者,也许我弄错了,我得到了正确格式的数据,但我的表示有问题。
我应该改用 lxml.fromstring 并使用 encoding 参数吗?
谢谢, g0m3z
解决方案:
实际上我的代码没有问题,但数据的表示。第一个代码实现工作正常。
我将结果加载到字典中,当我一次打印整个字典时,它会错误地显示 unicode 字符。但是,如果我仅根据键打印结果字典的一项,则它正确表示 unicode 字符。所以它有效!有趣的。感谢此线程上的每个人提供宝贵的 cmets!
【问题讨论】:
-
既然知道是iso-8859-2,为什么还要告诉解析器编码是utf-8?尝试使用
parser = etree.HTMLParser(encoding="iso-8859-2")看看是否能解决您的问题。 -
对不起,我忘了提到我尝试了 iso-8859-2 编码,但我仍然有转义字符
-
+1 用于实际使用解析器,而不是像 90% 的 SO 用户喜欢的那样尝试使用正则表达式解析 HTML。
标签: python unicode html-parsing lxml