zoukankan      html  css  js  c++  java
  • 解决Python2.7的UnicodeEncodeError:'ascii' codec can't encode characters in position 0-78: ordinal not in range(128)异常错误

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

    大家都知道,在使用python进行网络爬虫时,最头疼的就是转码问题,下面是我在编写完爬虫代码后,进行往“.txt”文件中保存上遇到的错误。查找资料最终解决问题,文章转自其它博客,这里只做我的总结,为使更多伙伴避免入坑。

    Python程序如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    # -*- coding: UTF-8 -*-
    import sqlite3
     
    def gsel(cur):
        cur.execute("SELECT * FROM collection")
     
    def main():
        conn = sqlite3.connect("build.db3")
        cur = conn.cursor()
        gsel(cur)
        # conn.commit()
        rs = cur.fetchall()
     
        fp = open("output.txt", "w")
        for row in rs:
            fp.write(row[1]) # 读取并写入第2列数据
     
    if __name__ == '__main__':
        main()

    代码上面应该没有什么问题,Python使用的是版本2.7,但是在运行的时候出现了异常错误UnicodeEncodeError

    Traceback (most recent call last):
      File "makedb.py", line 33, in 
        main()
      File "makedb.py", line 30, in main
        fp.write(row[1])
    UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-78: ordinal not in range(128)
    

    本来以为数据读取错误,我特将fp.write改成print,结果数据全部读取并显示在命令控制台上了,证明代码是没有问题的,仔细看了下异常信息,貌似是因为编码问题:Unicode编码与ASCII编码的不兼容,其实这个Python脚本文件是由utf-8编码的,同时SQlite3数据库存取的也是UTF-8格式,Python默认环境编码通过下面的方法可以获取:

    import sys
    print sys.getdefaultencoding()
    # 'ascii'

    基本上是ascii编码方式,由此Python自然调用ascii编码解码程序去处理字符流,当字符流不属于ascii范围内,就会抛出异常(ordinal not in range(128))。

    解决的方案很简单,修改默认的编码模式,很多朋友会想到setdefaultencoding,是的,我们可以通过sys.setdefaultencoding(‘utf-8’)来将当前的字符处理模式修改为utf-8编码模式,值得注意的是,如果单纯这么调用的话,Python会抛出一个AttributeError异常:

    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'module' object has no attribute 'setdefaultencoding'

    竟然说sys没有setdefaultencoding的方法,其实sys是有这个方法的,但是要请出她老人家需要调用一次reload(sys),很奇怪,是么?如果有谁知道原因的话,还望不吝赐教。

    import sys
    reload(sys)
    sys.setdefaultencoding('utf-8')

    好了,通过上面短短的三行,我们算是很好的解决了这个问题了,同样的方式也可以应用到UnicodeDecodeError上。当然这个技巧来自于网络,我还找到其他特别的办法,但是感觉还是这个比较靠谱,有童鞋说:我们将Python 2.x系列升级到Python 3.x系列就可以了,小小的问题犯不着升级吧,毕竟2到3还是要有个过渡的。

    最后,我将文章一开始的代码更改如下:

    # -*- coding: UTF-8 -*-
     
    import sys     # 1
    import sqlite3
     
    def gsel(cur):
        cur.execute("SELECT * FROM collection")
     
    def main():
        reload(sys)                         # 2
        sys.setdefaultencoding('utf-8')     # 3
     
        conn = sqlite3.connect("build.db3")
        cur = conn.cursor()
        gsel(cur)
        # conn.commit()
        rs = cur.fetchall()
     
        fp = open("output.txt", "w")
        for row in rs:
            fp.write(row[1])
     
    if __name__ == '__main__':
        main()

    末尾补充: 上面是收集自网络的该问题的解决方法,在我使用上面方法后还是爆出:“空的字符无法进行str拼接”,此时,肯定你的xpath取值时有某一个字段是空的,只要在你要取得字段后添加:

    # #状态开始日期
    items['start_date'] = site.xpath('td[7]/text()')[0] if len(site.xpath('td[7]/text()'))>0 else str('空')
    # #任务类型
    items['task_genre'] = site.xpath('td[8]/text()')[0] if len(site.xpath('td[8]/text()'))>0 else str('空')

    即可完美解决。

  • 相关阅读:
    eclipse fail to create java virtual machine
    sas软件连接Oracle数据库的办法
    JAVA中数据的读取与写入,不同类型数据的转换
    二维数组的在函数中的传递
    【转】值传递与引用传递
    【转】深拷贝与浅拷贝
    (转)JS报表控件highcharts应用
    highstocks.js使用指南
    (转)Highcharts使用指南(出处:http://liuhaorain.cnblogs.com )
    jQuery实现checkbox全选,反选
  • 原文地址:https://www.cnblogs.com/fanjp666888/p/7754190.html
Copyright © 2011-2022 走看看