每个urllib.request都会出现UnicodeDecodeError错误

时间:2017-05-27 05:43:17

标签: python utf-8 urllib

当我在Python3中使用urllib来获取网页的HTML代码时,我使用以下代码:

def getHTML(url):
    request = Request(url)
    request.add_header('User-Agent', 'Mozilla/5.0')
    html = urlopen(request).read().decode('utf-8')
    print(html)
    return html

但是,每次出现错误都会失败:

Traceback (most recent call last):
  File "/Users/chris/Documents/Code/Python/HLTV Parser/getTeams.py", line 56, in <module>
getHTML('https://www.hltv.org/team/7900/spirit-academy')
  File "/Users/chris/Documents/Code/Python/HLTV Parser/getTeams.py", line 53, in getHTML
print(html)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 10636-10638: ordinal not in range(128)
[Finished in 1.14s]

page是UTF-8,我根据urllib文档正确解码。该页面不是gzip压缩或在我可以告诉的另一个charset中。

url.info().get_charset()会为页面返回None,但元标记会指定UTF-8。在任何程序中查看HTML都没有问题。

我不想使用任何外部库。

有解决方案吗?到底是怎么回事?这适用于以下Python2代码:

def getHTML(url):
    opener = urllib2.build_opener()
    opener.addheaders = [('User-Agent', 'Mozilla/5.0')]
    response = opener.open(url)
    html = response.read()
    return html

2 个答案:

答案 0 :(得分:0)

您不需要decode('utf-8')

以下内容应该返回获取的html。

def getHTML(url):
    request = Request(url)
    request.add_header('User-Agent', 'Mozilla/5.0')
    html = urlopen(request).read()
    return html

答案 1 :(得分:0)

在那里,发现你的错误,解析完成得很好,一切都评估得很好。但是当你仔细阅读Traceback时:

Traceback (most recent call last): File 
"/Users/chris/Documents/Code/Python/HLTV Parser/getTeams.py", line 56, in <module> 
 getHTML('hltv.org/team/7900/spirit-academy') File 
"/Users/chris/Documents/Code/Python/HLTV Parser/getTeams.py", line 53, in getHTML 
 print(html) 
UnicodeEncodeError: 'ascii' codec can't encode characters in position 10636-10638: ordinal not in range(128) 
[Finished in 1.14s]

错误是由print语句引起的,正如您所看到的,这是在追溯print(html)中。

这是一个常见的例外,它只是告诉您,使用您当前的系统编码,某些文本无法打印到控制台。一个简单的解决方案是添加print(html.encode('ascii', 'ignore'))以忽略所有不可打印的字符。您仍然可以使用html执行所有其他操作,只是您无法打印它。

如果您想要更好的“修复”,请查看此内容:https://wiki.python.org/moin/PrintFails

btw:re模块可以搜索字节字符串。完全按原样复制,工作:

import re
print(re.findall(b'hello', b'hello world'))