zoukankan      html  css  js  c++  java
  • python3中编码与解码之Unicode与bytes(转帖)

    今天玩Python爬虫,下载一个网页,然后把所有内容写入一个txt文件中,出现错误;

    TypeError: write() argument must be str, not bytes

    AttributeError: 'URLError' object has no attribute 'code'

    UnicodeEncodeError: 'gbk' codec can't encode character 'xa0' inposition 5747: illegal multibyte sequence

    一看就是编码问题,不懂,度娘上面这方面讲得不多,感觉没说清楚,自己研究了一晚上,摸出了一点门道。

    从头说起,由于各国语言文字不同,起初要在计算机中表示,就有了各种各样的编码(例如中文的gb2312)。但是这样就出现了兼容性的问题,所以就有了Unicode,也就是所谓的万国码,python3中字符串类型str就是以Unicode编码格式编码,所以我们在Python3 中看到多种语言文字的字符串而不会出现乱码。

    编码是一种用一种特定的方式对抽象字符(Unicode)转换为二进制形式(bytes)进行表示,也就是python3中的encode。解码就是对用特定方式表示的二进制数据用特定的方式转化为Unicode,也就是decode。

    下图就是编码的核心:

    一、字符的编码:

    Python对于bites类型的数据用带‘b‘前缀的单引号活双引号表示。

    下面关于字符编码解码的代码很好的解释了上面的流程图:

    s='你好'
    print(s)#输出结果:你好
    print(type(s))#输出结果:<class 'str'>
    s=s.encode('UTF-8')
    print(s)#输出结果:b'xe4xbdxa0xe5xa5xbd'
    print(type(s))#输出结果:<class 'bytes'>
    s=s.decode('UTF-8')
    print(s)#输出结果:你好
    print(type(s))#输出结果:<class 'str'>

    多说一句,如果你对str类型字符进行decode会报错,同理,对bytes类型进行encode也会报错。

    二、文件编码

    在python 3 中字符是以Unicode的形式存储的,当然这里所说的存储是指存储在计算机内存当中,如果是存储在硬盘里,Python 3的字符是以bytes形式存储,也就是说如果要将字符写入硬盘,就必须对字符进行encode。对上面这段话再解释一下,如果要将str写入文件,如果以‘w’模式写入,则要求写入的内容必须是str类型;如果以‘wb’形式写入,则要求写入的内容必须是bytes类型。文章开头出现的集中错误,就是因为写入模式与写入内容的数据类型不匹配造成的。

    s1 = '你好'
    #如果是以‘w’的方式写入,写入前一定要进行encoding,否则会报错
    with open('F:\1.txt','w',encoding='utf-8') as f1:
        f1.write(s1)
    s2 = s1.encode("utf-8")#转换为bytes的形式
    #这时候写入方式一定要是‘wb’,且一定不能加encoding参数
    with open('F:\2.txt','wb') as f2:
        f2.write(s2)

    有的人会问,我在系统里面用文本编辑器打开以bytes形式写入的2.txt文件,发现里面显示的是‘你好’,而不是‘b'xe4xbdxa0xe5xa5xbd'’,因为文本文档打开2.txt时,又会对它进行decode,然后才给你看到。

    三、网页的编码

    网页编码和文件编码方法差不多,如下urlopen下载下来的网页read()且用decoding(‘utf-8’)解码,那就必须以‘w’的方式写入文件。如果只是read()而不用encoding(‘utf-8’)进行编码,一定要以‘wb’方式写入:

    以‘w’方式写入时:

    response= url_open('http://blog.csdn.net/gs_zhaoyang/article/details/13768925 ' ,timeout=5 )
    #此处以UTF-8方式进行解码,解码后的数据以unicode的方式存储在html中
    html = response.read().decode('UTF-8')
    print(type(html))#输出结果:<class 'str'>
    #这时写入方式一定要加encoding,以encoding
    # 即UTF-8的方式对二进制数据进行编码才能写入
    with open('F:DownloadAppDatahtml.txt',"w" , encoding='UTF-8') as f:
        f.write(html)

    以‘wb’方式写入:

    response= url_open('http://blog.csdn.net/gs_zhaoyang/article/details/13768925 ' ,timeout=5 )
    html = response.read()#此处不需要进行解码,下载下来
    print(type(html))#输出结果:<class 'bytes'>
    with open('F:DownloadAppDatahtml.txt',"wb" ) as f:
        f.write(html)

    如果要在Python3中,对urlopen下来的网页进行字符搜索,肯定也要进行decode,例如使用lxml.etree就必须进行decode。
    ————————————————
    版权声明:本文为CSDN博主「奥辰_」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/chb4715/article/details/79104299

  • 相关阅读:
    Scribd每月共有超过两亿个访客、累积数亿篇以上的文件档案,Alexa全球排名200以内
    Archive.org:互联网档案馆
    《技术、沟通、协作,引发的思考》
    linux记事工具:RedNotebook Lifeograph Kontact ThotKeeper
    HTTP的请求头标签 If-Modified-Since
    meta标签 使用说明(http-equiv、refresh、seo)
    XX-net https://github.com/XX-net/XX-Net
    XScreenSaver强大的锁屏工具
    JavaScript data types and data structures
    Firefox disable search in the address bar
  • 原文地址:https://www.cnblogs.com/sidianok/p/11769019.html
Copyright © 2011-2022 走看看