Hom*_*lli 1222 python unicode beautifulsoup python-2.x python-unicode
我在处理从不同网页(在不同网站上)获取的文本中的unicode字符时遇到问题.我正在使用BeautifulSoup.
问题是错误并不总是可重现的; 它有时适用于某些页面,有时候,它会通过抛出一个UnicodeEncodeError
.我已经尝试了几乎所有我能想到的东西,但是我没有找到任何可以持续工作的东西而不会抛出某种与Unicode相关的错误.
导致问题的代码部分之一如下所示:
agent_telno = agent.find('div', 'agent_contact_number')
agent_telno = '' if agent_telno is None else agent_telno.contents[0]
p.agent_info = str(agent_contact + ' ' + agent_telno).strip()
Run Code Online (Sandbox Code Playgroud)
以下是运行上述代码段时在SOME字符串上生成的堆栈跟踪:
Traceback (most recent call last):
File "foobar.py", line 792, in <module>
p.agent_info = str(agent_contact + ' ' + agent_telno).strip()
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa0' in position 20: ordinal not in range(128)
Run Code Online (Sandbox Code Playgroud)
我怀疑这是因为某些页面(或更具体地说,来自某些站点的页面)可能被编码,而其他页面可能是未编码的.所有这些网站都位于英国,并提供供英国消费的数据 - 因此,没有与内部化或处理用英语以外的任何文字处理的文本相关的问题.
有没有人有任何想法如何解决这个问题,以便我可以一致地解决这个问题?
agf*_*agf 1298
您需要阅读Python Unicode HOWTO.这个错误是第一个例子.
基本上,停止使用str
从unicode转换为编码的文本/字节.
相反,正确使用.encode()
编码字符串:
p.agent_info = u' '.join((agent_contact, agent_telno)).encode('utf-8').strip()
Run Code Online (Sandbox Code Playgroud)
或者完全以unicode工作.
And*_*rew 424
这是一个经典的python unicode痛点!考虑以下:
a = u'bats\u00E0'
print a
=> batsà
Run Code Online (Sandbox Code Playgroud)
到目前为止一切都很好,但如果我们调用str(a),让我们看看会发生什么:
str(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe0' in position 4: ordinal not in range(128)
Run Code Online (Sandbox Code Playgroud)
噢,这不会对任何人有任何好处!要修复错误,请使用.encode显式编码字节并告诉python要使用的编解码器:
a.encode('utf-8')
=> 'bats\xc3\xa0'
print a.encode('utf-8')
=> batsà
Run Code Online (Sandbox Code Playgroud)
Voil\u00E0!
问题是,当你调用str()时,python使用默认的字符编码来尝试编码你给它的字节,在你的情况下有时代表unicode字符.要解决这个问题,你必须告诉python如何使用.encode('whatever_unicode')处理你给它的字符串.大多数时候,使用utf-8应该没问题.
有关此主题的精彩论述,请参阅Ned Batchelder的PyCon演讲:http://nedbatchelder.com/text/unipain.html
小智 200
我发现优雅的工作方法可以删除符号并继续将字符串保存为字符串如下:
yourstring = yourstring.encode('ascii', 'ignore').decode('ascii')
Run Code Online (Sandbox Code Playgroud)
重要的是要注意使用ignore选项是危险的,因为它会静默地从使用它的代码中删除任何unicode(和国际化)支持,如此处所示(转换unicode):
>>> u'City: Malmö'.encode('ascii', 'ignore').decode('ascii')
'City: Malm'
Run Code Online (Sandbox Code Playgroud)
Ash*_*win 144
好吧,我尝试了一切,但它没有帮助,谷歌搜索后我认为以下,它有所帮助.python 2.7正在使用中.
# encoding=utf8
import sys
reload(sys)
sys.setdefaultencoding('utf8')
Run Code Online (Sandbox Code Playgroud)
max*_*olk 80
导致偶数打印失败的一个微妙问题是您的环境变量设置错误,例如.这里LC_ALL设置为"C".在Debian中,他们不鼓励设置它:Debian wiki on Locale
$ echo $LANG
en_US.utf8
$ echo $LC_ALL
C
$ python -c "print (u'voil\u00e0')"
Traceback (most recent call last):
File "<string>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe0' in position 4: ordinal not in range(128)
$ export LC_ALL='en_US.utf8'
$ python -c "print (u'voil\u00e0')"
voilà
$ unset LC_ALL
$ python -c "print (u'voil\u00e0')"
voilà
Run Code Online (Sandbox Code Playgroud)
Ani*_*esh 27
对我来说,有用的是:
BeautifulSoup(html_text,from_encoding="utf-8")
Run Code Online (Sandbox Code Playgroud)
希望这有助于某人.
Phi*_*asa 24
我实际上发现在我的大多数情况下,剥离这些字符要简单得多:
s = mystring.decode('ascii', 'ignore')
Run Code Online (Sandbox Code Playgroud)
ken*_*orb 22
问题是您正在尝试打印unicode字符,但您的终端不支持它.
您可以尝试安装language-pack-en
包来修复:
sudo apt-get install language-pack-en
Run Code Online (Sandbox Code Playgroud)
它为所有支持的软件包(包括Python)提供英文翻译数据更新.如有必要,请安装不同的语言包(取决于您尝试打印的字符).
在某些Linux发行版中,需要确保正确设置默认的英语语言环境(因此可以通过shell /终端处理unicode字符).有时,安装它比手动配置更容易.
然后在编写代码时,请确保在代码中使用正确的编码.
例如:
open(foo, encoding='utf-8')
Run Code Online (Sandbox Code Playgroud)
如果您仍然有问题,请仔细检查您的系统配置,例如:
你的语言环境文件(/etc/default/locale
),应该有例如
LANG="en_US.UTF-8"
LC_ALL="en_US.UTF-8"
Run Code Online (Sandbox Code Playgroud)
要么:
LC_ALL=C.UTF-8
LANG=C.UTF-8
Run Code Online (Sandbox Code Playgroud)价值LANG
/ LC_CTYPE
壳.
检查shell支持的语言环境:
locale -a | grep "UTF-8"
Run Code Online (Sandbox Code Playgroud)在新VM中演示问题和解决方案.
初始化和配置VM(例如使用vagrant
):
vagrant init ubuntu/trusty64; vagrant up; vagrant ssh
Run Code Online (Sandbox Code Playgroud)
请参阅:可用的Ubuntu框..
打印unicode字符(如商标符号™
):
$ python -c 'print(u"\u2122");'
Traceback (most recent call last):
File "<string>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2122' in position 0: ordinal not in range(128)
Run Code Online (Sandbox Code Playgroud)现在安装language-pack-en
:
$ sudo apt-get -y install language-pack-en
The following extra packages will be installed:
language-pack-en-base
Generating locales...
en_GB.UTF-8... /usr/sbin/locale-gen: done
Generation complete.
Run Code Online (Sandbox Code Playgroud)现在问题应该解决:
$ python -c 'print(u"\u2122");'
™
Run Code Online (Sandbox Code Playgroud)否则,请尝试以下命令:
$ LC_ALL=C.UTF-8 python -c 'print(u"\u2122");'
™
Run Code Online (Sandbox Code Playgroud)Jos*_*udi 21
试试这可能会解决,
# encoding=utf8
import sys
reload(sys)
sys.setdefaultencoding('utf8')
Run Code Online (Sandbox Code Playgroud)
And*_*yko 16
在脚本开头添加以下行(或作为第二行):
# -*- coding: utf-8 -*-
Run Code Online (Sandbox Code Playgroud)
这是python源代码编码的定义.更多信息在PEP 263.
Buv*_*inJ 14
这是对其他一些所谓的"警察出局"答案的重复.尽管这里有抗议活动,但有些情况下,简单地丢弃麻烦的角色/弦乐是一个很好的解决方案.
def safeStr(obj):
try: return str(obj)
except UnicodeEncodeError:
return obj.encode('ascii', 'ignore').decode('ascii')
except: return ""
Run Code Online (Sandbox Code Playgroud)
测试它:
if __name__ == '__main__':
print safeStr( 1 )
print safeStr( "test" )
print u'98\xb0'
print safeStr( u'98\xb0' )
Run Code Online (Sandbox Code Playgroud)
结果:
1
test
98°
98
Run Code Online (Sandbox Code Playgroud)
建议:您可能想要将此功能命名为toAscii
?这是一个偏好问题.
ken*_*orb 14
在外壳中:
通过以下命令查找支持的UTF-8语言环境:
locale -a | grep "UTF-8"
Run Code Online (Sandbox Code Playgroud)在运行脚本之前将其导出,例如:
export LC_ALL=$(locale -a | grep UTF-8)
Run Code Online (Sandbox Code Playgroud)
或手动像:
export LC_ALL=C.UTF-8
Run Code Online (Sandbox Code Playgroud)通过打印特殊字符进行测试,例如™
:
python -c 'print(u"\u2122");'
Run Code Online (Sandbox Code Playgroud)以上在Ubuntu中测试过。
我总是将下面的代码放在python文件的前两行中:
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
Run Code Online (Sandbox Code Playgroud)
唉,这至少在 Python 3 中有效......
蟒蛇 3
有时错误出在环境变量中,因此
import os
import locale
os.environ["PYTHONIOENCODING"] = "utf-8"
myLocale=locale.setlocale(category=locale.LC_ALL, locale="en_GB.UTF-8")
...
print(myText.encode('utf-8', errors='ignore'))
Run Code Online (Sandbox Code Playgroud)
在编码中忽略错误的地方。
较晚回答,但此错误与您的终端编码不支持某些字符有关。
\n我python3
使用以下方法修复了它:
import sys\nimport io\n\nsys.stdout = io.open(sys.stdout.fileno(), 'w', encoding='utf8')\nprint("\xc3\xa9, \xc3\xa0, ...")\n
Run Code Online (Sandbox Code Playgroud)\n
这里有简单的辅助函数.
def safe_unicode(obj, *args):
""" return the unicode representation of obj """
try:
return unicode(obj, *args)
except UnicodeDecodeError:
# obj is byte string
ascii_text = str(obj).encode('string_escape')
return unicode(ascii_text)
def safe_str(obj):
""" return the byte string representation of obj """
try:
return str(obj)
except UnicodeEncodeError:
# obj is unicode
return unicode(obj).encode('unicode_escape')
Run Code Online (Sandbox Code Playgroud)
我刚刚使用了以下内容:
\n\nimport unicodedata\nmessage = unicodedata.normalize("NFKD", message)\n
Run Code Online (Sandbox Code Playgroud)\n\n检查文档对此有何说明:
\n\n\n\n\nunicodedata.normalize(form, unistr) 返回 Unicode 字符串 unistr 的范式。表单的有效值为 \xe2\x80\x98NFC\xe2\x80\x99、\xe2\x80\x98NFKC\xe2\x80\x99、\n \xe2\x80\x98NFD\xe2\x80\x99 和 \xe2\ x80\x98NFKD\xe2\x80\x99。
\n\nUnicode 标准基于规范等效性和兼容性等效性的定义,定义了 Unicode 字符串的各种规范化形式。在 Unicode 中,多个字符可以用不同的方式表示。例如,字符 U+00C7 (LATIN\n CAPITAL LETTER C WITH CEDILLA) 也可以表示为序列\n U+0043 (LATIN CAPITAL LETTER C) U+0327 (COMBINING CEDILLA)。
\n\n对于每个字符,有两种范式:范式 C 和\n 范式 D。范式 D (NFD) 也称为规范\n 分解,并将每个字符转换为其分解形式。\n 范式 C ( NFC)首先应用规范分解,然后再次组合预先组合的字符。
\n\n除了这两种形式之外,还有两种基于兼容性等价性的附加范式。在 Unicode 中,支持某些字符,这些字符通常与其他字符统一。例如,U+2160(罗马数字一)实际上与 U+0049\n(拉丁文大写字母 I)相同。但是,它在 Unicode 中受支持,以便与现有字符集(例如 gb2312)兼容。
\n\n范式 KD (NFKD) 将应用兼容性分解,即用其等效字符替换所有兼容性字符。范式 KC (NFKC) 首先应用兼容性分解,然后应用规范组合。
\n\n即使两个 unicode 字符串已标准化并且对于人类读者来说看起来相同,但如果其中一个具有组合字符而另一个没有 xe2x80x99t,则它们比较起来可能不相等。
\n
帮我解决了 简单又容易。
\n以下解决方案对我有用,刚刚添加
u“字符串”
(将字符串表示为 unicode)在我的字符串之前。
result_html = result.to_html(col_space=1, index=False, justify={'right'})
text = u"""
<html>
<body>
<p>
Hello all, <br>
<br>
Here's weekly summary report. Let me know if you have any questions. <br>
<br>
Data Summary <br>
<br>
<br>
{0}
</p>
<p>Thanks,</p>
<p>Data Team</p>
</body></html>
""".format(result_html)
Run Code Online (Sandbox Code Playgroud)
推荐的解决方案对我来说不起作用,而且我可以忍受转储所有非 ASCII 字符,所以
s = s.encode('ascii',errors='ignore')
Run Code Online (Sandbox Code Playgroud)
这给我留下了一些不会引发错误的东西。
在一般情况下,将此不受支持的编码 字符串(比方说data_that_causes_this_error
)写入某个文件(例如results.txt
),这是有效的
f = open("results.txt", "w")
f.write(data_that_causes_this_error.encode('utf-8'))
f.close()
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1563831 次 |
最近记录: |