以下代码从网页中提取链接并在浏览器中显示。使用大量UTF-8编码的网页,效果很好。但是法语维基百科页面http://fr.wikipedia.org/wiki/États_unis例如会产生错误。
# -*- coding: utf-8 -*-
print 'Content-Type: text/html; charset=utf-8\n'
print '''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Show Links</title>
</head>
<body>'''
import urllib2, lxml.html as lh
def load_page(url):
headers = {'User-Agent' : 'Mozilla/5.0 (compatible; testbot/0.1)'}
try:
req = urllib2.Request(url, None, headers)
response = urllib2.urlopen(req)
page = response.read()
return page
except:
print '<b>Couldn\'t load:', url, '</b><br>'
return None
def show_links(page):
tree = lh.fromstring(page)
for node in tree.xpath('//a'):
if 'href' in node.attrib:
url = node.attrib['href']
if '#' in url:
url=url.split('#')[0]
if '@' not in url and 'javascript' not in url:
if node.text:
linktext = node.text
else:
linktext = '-'
print '<a href="%s">%s</a><br>' % (url, linktext.encode('utf-8'))
page = load_page('http://fr.wikipedia.org/wiki/%C3%89tats_unis')
show_links(page)
print '''
</body>
</html>
'''
我收到以下错误:
Traceback (most recent call last):
File "C:\***\question.py", line 42, in <module>
show_links(page)
File "C:\***\question.py", line 39, in show_links
print '<a href="%s">%s</a><br>' % (url, linktext.encode('utf-8'))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 3: ordinal not in range(128)
我的系统:Python 2.6(Windows),lxml 2.3.3,Apache Server(显示结果)
我做错了什么?
答案 0 :(得分:2)
您还需要对url
进行编码。
问题可能类似于:
>>> "%s%s" % (u"", "€ <-non-ascii char in a bytestring")
Traceback (most recent call last):
File "<input>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 0: ordinal not in
range(128)
但这有效:
>>> "%s%s" % (u"".encode('utf-8'), "€ <-non-ascii char in a bytestring")
'\xe2\x82\xac <-non-ascii char in a bytestring'
空Unicode字符串强制将整个表达式转换为Unicode。因此,您会看到Unicode Decode 错误。
一般来说,混合Unicode和字节串是个坏主意。它可能看似有效,但迟早会破裂。收到文本后立即将文本转换为Unicode,处理它然后将其转换为I / O的字节。
答案 1 :(得分:1)
lxml返回bytestrings而不是unicode。在编码为utf-8之前,使用页面所服务的任何编码对 decode
字节串进行unicode可能更好。
如果您的文字已经在utf-8中,则无需进行任何编码或解码 - 只需执行该操作即可。
但是,如果您的linktext类型为unicode
(正如您所说),那么它是一个unicode字符串(每个元素代表一个unicode代码点),而编码为utf-8应该可以很好地工作。
我怀疑问题是你的url
字符串也是一个unicode字符串,并且在被替换成你的字节字符串之前还需要编码为utf-8。