我正在Python 3.3上使用BeautifulSoup构建一个Web scraper。
但是我遇到了一个问题,导致我无法获得可以与BeautifulSoup一起使用的有效strin *。那就是:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe0 in position 7047: invalid continuation byte
我知道有几十个类似的问题,但到目前为止我还没有找到一种方法可以帮助我诊断出以下代码的错误:
import urllib.request
URL = "<url>" # sorry, I cannot show the url for privacy reasons, but it's a normal html document
page = urllib.request.urlopen(URL)
page = page.read().decode("utf-8") # from bytes to <source encodings>
正如我猜测我注意到这个错误只发生在一些URL而不是其他的。即使有这个相同的错误,我直到昨天才有这个错误。然后今天我再次运行程序并弹出错误..
有关如何诊断错误的任何线索?
答案 0 :(得分:2)
您应该不解码响应。首先,您错误地认为响应是UTF-8编码的(它不是,如错误所示),但更重要的是,BeautifulSoup将为您检测编码 。请参阅BeautifulSoup文档的Encodings section。
将一个字节字符串传递给BeautifulSoup,它将使用任何<meta>
标头来宣告正确的编码,或者为您自动检测编码做得很好。
如果自动检测失败,您可以始终回退到服务器提供的编码:
encoding = page.info().get_charset()
page = page.read()
soup = BeautifulSoup(page)
if encoding is not None and soup.original_encoding != encoding:
print('Server and BeautifulSoup disagree')
print('Content-type states it is {}, BS4 states thinks it is {}'.format(encoding, soup.original_encoding)
print('Forcing encoding to server-supplied codec')
soup = BeautifulSoup(page, from_encoding=encoding)
这仍然会将实际解码留给BeautifulSoup,但如果服务器在charset
标头中包含Content-Type
参数,则上面假设服务器配置正确并强制BeautifulSoup使用该编码。