在学习requests库爬取网页的时候,出现了“解决Python2.7的UnicodeEncodeError: ‘ascii’ codec can’t encode异常错误”的错误。
# -*-coding:utf-8-*-
import requests
from bs4 import BeautifulSoup
import bs4
def getHTMLText(url):
try:
r = requests.get(url, timeout=30)
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except:
return ''
def fillUnivList(ulist, html):
soup = BeautifulSoup(html, 'html.parser')
for tr in soup.find('tbody').children:
if isinstance(tr, bs4.element.Tag):
tds = tr('td')
ulist.append([tds[0].string, tds[1].string, tds[2].string])
def printUnivList(ulist, num):
print('{:^10}\t{:^6}\t{:^10}'.format('range', 'University', 'score'))
for i in range(num):
u = ulist[i]
print('{:^10}\t{:^6}\t{:^10}'.format(u[0], u[1], u[2]))
# print('Suc'+str(num))
def main():
uinfo = []
url = 'http://www.zuihaodaxue.cn/zuihaodaxuepaiming2018.html'
html = getHTMLText(url)
fillUnivList(uinfo, html)
printUnivList(uinfo, 20)
#main()
if __name__ == '__main__':
main()
代码上面应该没有什么问题,Python使用的是版本2.7,但是在运行的时候出现了异常错误UnicodeEncodeError,输出结果:
从出错原因来看,大致是因为编码的问题,因为输出的内容中有中文,Unicode嘛与ASCII码不兼容,由于这个脚本使用的是utf-8编码的,但是python的默认编码方式为Ascii码,可以通过以下命令进行查询:
>>> import sys
>>> print sys.getdefaultencoding()
ascii
因为Ascii的范围为0-128,默认为Ascii,故而python在处理的时候自然调用Ascii码进行处理,因此在处理汉字的时候就超出了Ascii的范围,从而抛出ordinal not in range的异常错误。
那如何修改呢?
通过修改默认额编码方式,即修改 setdefaultencoding
import sys
sys.setdefaultencoding('utf-8')
但是 setdefaultencoding 就是 sys 的方法,其实是这里的 sys.setdefaultencoding('utf-8')没有生效的原因,因为在python27/Lib/目录下,在site.py文件中:
# Remove sys.setdefaultencoding() so that users cannot change the
# encoding after initialization. The test for presence is needed when
# this module is run as a script, because this code is executed twice.
if hasattr(sys, "setdefaultencoding"):
del sys.setdefaultencoding
为什么要查看site.py文件呢,因为在加载python模块的时候,会加载site.py模块
C:\Users\rhx>python -v
# installing zipimport hook
import zipimport # builtin
# installed zipimport hook
# C:\Python27\lib\site.pyc matches C:\Python27\lib\site.py
因此第一次导入后,再次sys.setdefaultencoding执行的时候会被删除,所以需要重新导入一次 reload(os)。明白原理之后,这样就有两种方式设置python的默认编码了。
1、设置为 utf-8 的编码格式
import sys
reload(sys)
sys.setdefaultencoding('utf8')
2、在python的Lib\site-packages文件夹下新建一个sitecustomize.py,内容为
# encoding=utf8
import sys
reload(sys)
sys.setdefaultencoding('utf8')
此时重启python解释器,执行sys.getdefaultencoding(),发现编码已经被设置为utf8的了,多次重启之后,效果相同,这是因为系统在python启动的时候,自行调用该文件,设置系统的默认编码,而不需要每次都手动的加上解决代码,属于一劳永逸的解决方法。
这样在模块的开始部分加入以上设置即可。