首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Python中无错误地将Unicode转换为ASCII

在Python中无错误地将Unicode转换为ASCII
EN

Stack Overflow用户
提问于 2010-03-03 01:52:43
回答 12查看 505.7K关注 0票数 187

我的代码只是抓取一个网页,然后将其转换为Unicode。

代码语言:javascript
复制
html = urllib.urlopen(link).read()
html.encode("utf8","ignore")
self.response.out.write(html)

但是我得到了一个UnicodeDecodeError

代码语言:javascript
复制
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尝试。我可以删除导致问题的任何代码字节而不是得到错误吗?

EN

回答 12

Stack Overflow用户

回答已采纳

发布于 2010-03-03 09:42:13

2018更新:

截至2018年2月,使用像gzip这样的压缩已经变成了quite popular (大约73%的网站使用它,包括谷歌、YouTube、雅虎、维基百科、Reddit、Stack Overflow和Stack Exchange Network等大型网站)。

如果你像原始答案中那样使用this压缩的响应进行简单的解码,你会得到一个类似或类似于下面这样的错误:

UnicodeDecodeError:'utf8‘编解码器无法解码位置1中的字节0x8b :意外的代码字节

为了解码gzpipped响应,您需要添加以下模块(在Python 3中):

代码语言:javascript
复制
import gzip
import io

备注: In Python 2 you'd use StringIO instead of io

然后,您可以像这样解析出内容:

代码语言:javascript
复制
response = urlopen("https://example.com/gzipped-ressource")
buffer = io.BytesIO(response.read()) # Use StringIO.StringIO(response.read()) in Python 2
gzipped_file = gzip.GzipFile(fileobj=buffer)
decoded = gzipped_file.read()
content = decoded.decode("utf-8") # Replace utf-8 with the source encoding of your requested resource

这段代码读取响应,并将字节放入缓冲区。然后,gzip模块使用GZipFile函数读取缓冲区。在此之后,可以再次将again文件读取为字节,并最终解码为正常可读的文本。

2010年的原始答案:

我们能否获得用于link的实际值

此外,当我们尝试.encode()一个已经编码的字节字符串时,我们通常会在这里遇到这个问题。因此,您可以先尝试解码它,如下所示

代码语言:javascript
复制
html = urllib.urlopen(link).read()
unicode_str = html.decode(<source encoding>)
encoded_str = unicode_str.encode("utf8")

举个例子:

代码语言:javascript
复制
html = '\xa0'
encoded_str = html.encode("utf8")

失败,错误为

代码语言:javascript
复制
UnicodeDecodeError: 'ascii' codec can't decode byte 0xa0 in position 0: ordinal not in range(128)

而:

代码语言:javascript
复制
html = '\xa0'
decoded_str = html.decode("windows-1252")
encoded_str = decoded_str.encode("utf8")

成功,没有错误。请注意,"windows-1252“是我用作示例的东西。这是我从chardet得到的,它有0.5的置信度,认为它是正确的!(对于1个字符长度的字符串,您期望的是什么)您应该将其更改为从.urlopen().read()返回的字节字符串的编码,以适用于您检索的内容。

我看到的另一个问题是,.encode()字符串方法返回修改后的字符串,并且不会就地修改源代码。因此,由于self.response.out.write(html)不是来自html.encode的编码字符串(如果这是您最初的目标),因此使用html是没有用的。

按照Ignacio的建议,检查源网页以了解从read()返回的字符串的实际编码。它要么在Meta标签中,要么在响应的ContentType头中。然后将其用作.decode()的参数。

但是,请注意,不应该假设其他开发人员有足够的责任来确保头部和/或元字符集声明与实际内容相匹配。(这是皮塔,是的,我应该知道,我以前就是其中之一)。

票数 108
EN

Stack Overflow用户

发布于 2010-03-03 01:56:46

代码语言:javascript
复制
>>> u'aあä'.encode('ascii', 'ignore')
'a'

使用响应中适当的meta标记或Content-Type标头中的字符集对返回的字符串进行解码,然后进行编码。

encode(encoding, errors)方法接受错误的自定义处理程序。除ignore之外,默认值为:

代码语言:javascript
复制
>>> u'aあä'.encode('ascii', 'replace')
b'a??'
>>> u'aあä'.encode('ascii', 'xmlcharrefreplace')
b'a&#12354;&#228;'
>>> u'aあä'.encode('ascii', 'backslashreplace')
b'a\\u3042\\xe4'

请参阅https://docs.python.org/3/library/stdtypes.html#str.encode

票数 235
EN

Stack Overflow用户

发布于 2011-10-16 11:31:37

作为Ignacio Vazquez-艾布拉姆斯答案的延伸

代码语言:javascript
复制
>>> u'aあä'.encode('ascii', 'ignore')
'a'

有时需要删除字符中的重音并打印基本表单。这可以通过以下命令完成

代码语言:javascript
复制
>>> import unicodedata
>>> unicodedata.normalize('NFKD', u'aあä').encode('ascii', 'ignore')
'aa'

您可能还希望将其他字符(如标点符号)转换为最接近的等效字符,例如,右单引号标记unicode字符在编码时不会转换为ascii撇号。

代码语言:javascript
复制
>>> print u'\u2019'
’
>>> unicodedata.name(u'\u2019')
'RIGHT SINGLE QUOTATION MARK'
>>> u'\u2019'.encode('ascii', 'ignore')
''
# Note we get an empty string back
>>> u'\u2019'.replace(u'\u2019', u'\'').encode('ascii', 'ignore')
"'"

尽管有更有效的方法来实现这一点。有关更多详细信息,请参阅此问题Where is Python's "best ASCII for this Unicode" database?

票数 127
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2365411

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档