Python: 'ascii' codec can't encode characters
我使用以下代码来抓取包含日文字符的网页:
1 2 3 4 5 6 7 8 9 10 11
| import urllib2
import bs4
import time
url = 'http://www.city.sapporo.jp/eisei/tiiki/toban.html'
pagecontent = urllib2.urlopen(url)
soup = bs4.BeautifulSoup(pagecontent.read().decode("utf8"))
print(soup.prettify())
print(soup) |
在一些机器中,代码工作正常,最后两个语句成功地打印了结果。但是,在某些机器中,最后一条语句只给出了错误
1
| UnicodeEncodeError 'ascii' codec can't encode characters in position 485-496: ordinal not in range(128), |
最后一句话为所有日文字符打印了奇怪的方块。
为什么同一代码在两台机器上的工作方式不同?我怎么修这个?
python版本2.6.6
BS4版本:4.1.0
- 您正在打印unicode数据,而python需要对其进行编码以匹配您的python终端或控制台编码。您需要修复您的终端,以正确地告诉Python它接受的编解码器。目前它告诉python只有ascii可以。您使用的控制台或终端是什么?
- @我正在使用Centos的默认终端。
- 然后设置LANG环境变量,参见cl.cam.ac.uk/~mgk25/unicode.html。
您需要正确配置环境区域设置;一旦设置了区域设置,在打印到终端时,python将自动接收它。
使用locale命令检查您的区域设置:
1 2 3 4 5 6 7 8 9
| $ locale
LANG="en_GB.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_CTYPE="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_ALL="en_US.UTF-8" |
注意我的区域设置中的.UTF-8;它告诉在终端中运行的程序我的终端使用了支持所有Unicode的utf-8编解码器。
您可以使用LANG环境变量在一个步骤中设置所有区域设置:
1
| export LANG="en_US.UTF-8" |
对于使用UTF-8编解码器的美国地区(日期和数字的打印方式)。准确地说,输出编解码器使用LC_CTYPE设置,而输出编解码器则默认为LANG值。
另请参见针对UNIX/Linux的非常全面的UTF-8和Unicode常见问题解答。
- 我刚检查了运行mac osx的机器,可以正确打印出结果,结果的"locale"设置为:lang=lc_collate="c"lc_ctype="utf-8"lc_messages="c"lc_monetary="c"lc_numeric="c"lc_time="c"lc_all=
- @shapeare:是的,因为输出编码取自LC_CTYPE。
- 我在~/.bashrc中添加了一行export LANG="ja_JP.UTF-8",然后运行source ~/.bashrc,它就生效了。但问题仍然存在,仍在说'ascii' codec can't encode characters。
- @shapeare:回溯仍指向print语句?import sys; print sys.stdout.encoding显示的是什么python检测到的?
- 回溯仍然指向打印语句。sys.stdout.encoding打印出ANSI_X3.4-1968。
- @shapeare:这显然不是您配置的正确的编解码器。(在壳中)locale表示LC_CTYPE设为什么?在python中,import os; print os.environ.get('LC_CTYPE'), os.environ.get('LANG')也很有趣,正如import locale; print locale.getdefaultlocale()一样。
- os.environ.get('LC_CTYPE')打印UTF-8,os.environ.get('LANG')打印ja-JP.UTF-8,locale.getdefaultlocale()产生错误unknown locale: UTF-8。
- @shapeare:有趣,与github.com/ieelectric/almir/issues/59症状相同
- @shapeare:错误表明没有加载您的_locale.so模块;import _locale为您做了什么?如果没有这个模块,python就没有要编码的utf-8编解码器。
- 现在我改为使用export LC_ALL=en_US.UTF-8 export LANG=en_US.UTF-8。print语句中的错误已经消失,但它仍然为每个日文字符打印正方形。在我的代码中添加import _locale不会引入任何错误。
- @shapeare:您的终端是否也设置为utf-8?告诉python打印utf-8字节只是这个过程中的一个步骤。