我的代码只是抓取一个网页,然后将其转换为 Unicode。
html = urllib.urlopen(link).read()
html.encode("utf8","ignore")
self.response.out.write(html)
但我得到一个 UnicodeDecodeError
:
Traceback (most recent call last):
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/webapp/__init__.py", line 507, in __call__
handler.get(*groups)
File "/Users/greg/clounce/main.py", line 55, in get
html.encode("utf8","ignore")
UnicodeDecodeError: 'ascii' codec can't decode byte 0xa0 in position 2818: ordinal not in range(128)
我认为这意味着 HTML 在某处包含一些错误形成的 Unicode 尝试。 我可以只删除导致问题的任何代码字节而不是收到错误吗?
原文由 themirror 发布,翻译遵循 CC BY-SA 4.0 许可协议
2018 年更新:
截至 2018 年 2 月,使用像
gzip
这样的压缩已经变得 非常流行(大约 73% 的网站使用它,包括谷歌、YouTube、雅虎、维基百科、Reddit、Stack Overflow 和 Stack Exchange Network 网站等大型网站).如果您像原始答案一样使用压缩响应进行简单解码,您将收到类似或类似的错误:
为了解码 gzpipped 响应,您需要添加以下模块(在 Python 3 中):
注意: 在 Python 2 中,您将使用
StringIO
而不是io
然后你可以像这样解析内容:
此代码读取响应,并将字节放入缓冲区。
gzip
模块然后使用GZipFile
函数读取缓冲区。之后,gzip 文件可以再次读入字节并最终解码为正常可读的文本。2010 年的原始答案:
我们可以获得用于
link
的实际值吗?此外,当我们尝试
.encode()
一个已经编码的字节字符串时,我们通常会在这里遇到这个问题。所以你可能会尝试先解码它举个例子:
失败
尽管:
成功无误。请注意,“windows-1252”是我用作 示例 的内容。我从 chardet 得到这个,它有 0.5 的信心它是正确的! (好吧,对于 1 个字符长度的字符串,您期望什么)您应该将其更改为从
.urlopen().read()
返回的字节字符串的编码,以适用于您检索到的内容。我看到的另一个问题是
.encode()
string 方法返回修改后的字符串并且没有修改源。所以拥有self.response.out.write(html)
是没有用的,因为 html 不是来自 html.encode 的编码字符串(如果那是你最初的目标)。正如 Ignacio 所建议的,检查源网页以了解从
read()
返回的字符串的实际编码。它要么在 Meta 标记之一中,要么在响应的 ContentType 标头中。然后将其用作.decode()
的参数。但是请注意,不应假设其他开发人员有足够的责任来确保标头和/或元字符集声明与实际内容匹配。 (这是 PITA,是的,我应该知道,我 以前就是 其中之一)。