解决Python2.7的UnicodeEncodeError: ‘ascii’ codec can’t encode异常错误

        在学习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启动的时候,自行调用该文件,设置系统的默认编码,而不需要每次都手动的加上解决代码,属于一劳永逸的解决方法。

这样在模块的开始部分加入以上设置即可。


猜你喜欢

转载自blog.csdn.net/rhx_qiuzhi/article/details/80208458