Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 528|回复: 0

python 编码问题之终极解决

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-4-13 13:38:14 | 显示全部楼层 |阅读模式

    结合之前遇到的坑以及下面贴的这篇文章, 总结几种python乱码解决方案,如果遇到乱码,不妨尝试一下?

    1,必备

    #encoding=utf-8

    2, python编程环境编码

    import sys
    reload(sys)
    sys.setdefaultencoding('utf8')

     

    3,不知道神马编码的时候用chardet查一下

    from chardet import detect  # detect(str),参数只能是str,不能是unicode编码的
    if not isinstance(line, unicode):
        line = line.decode(detect(line)['encoding']).rstrip().lower()

    4,mysql 的默认字符集 latin1,Latin1是ISO-8859-1的别名,有些环境下写作Latin-1,ISO-8859-1编码是单字节编码,向下兼容ASCII


    try
    : line = line.rstrip().decode("utf-8").lower() except UnicodeDecodeError: line = line.decode('latin-1').rstrip().lower() # 很多网页采用这种编码格式,爬取网页的时候会遇到

    5,读取oracle中文遇到问题的话,设置一下客户端编码

    import os
    os.environ['NLS_LANG']
    = 'SIMPLIFIED CHINESE_CHINA.UTF8'

     

    6, 非常好用的codecs, GB2312 < GBK < GB18030

    import codecs         # 下载的txt文本在mac上打开乱码,这样子转一下就好了
    fo = codecs.open('/Users/baidu/Desktop/spark/现代汉语常用词表.txt', 'rb', 'gbk') fo = codecs.open('/Users/baidu/Desktop/spark/现代汉语常用词表.txt', 'rb', 'utf8') fo = codecs.open('/Users/baidu/Desktop/spark/现代汉语常用词表.txt', 'rb', 'gb18030')

    混合编码的情况最烦人,可以采用try:....UnicodeDecodeError:....去尝试不同解码方法,或者用chardet先检测再解码(但是有些编码格式字符串找不到解码方式)

    总之,读进来先统一解码为unicode的格式,写出去都同一编写为utf-8格式(除非特殊要求)

    附上各种编码教程 http://www.crifan.com/character_encoding_charset_simpile_tutorial/

     

     

    【整理】Python中遇到"UnicodeDecodeError: ‘gbk’ codec can’t decode bytes in position 2-3: illegal multibyte sequence"之类的编码或解码的错误时如何处理
    原文  http://www.crifan.com/summary_python_unicodedecode_error_possible_reasons_and_solutions/


    问题参见:

    python2.7 urllib2 抓取新浪乱码

    中的:

    报错的异常是   
    UnicodeDecodeError: ‘gbk’ codec can’t decode bytes in position 2-3: illegal multibyte sequence

    此问题,还是很具有代表性的,此处,专门整理如下:

    【Python中如何处理UnicodeDecodeError和UnicodeEncodeError】

    简答:

    1.仔细分析错误的类型

    2.搞清自己处理的字符串是什么类型的

    3.然后换用这种的字符编码去编码或解码

    详解:

    以上面的错误:

    UnicodeDecodeError: ‘gbk’ codec can’t decode bytes in position 2-3: illegal multibyte sequence

    为例,去解释,如何处理这类问题:

    1.仔细分析错误的类型

    (1)错误是Unicode的编码还是解码

    对于此处,错误是:

    UnicodeDecodeError
    的类型的。

    此英文,对应的中文的含义,其实已经很清楚了:

    Unicode的解码(Decode)出现错误(Error)了

    而对于上面这句,我们可以推断出:

    你当前正在处理某种编码类型的字符串
    此处你要处理字符串,是想要将该字符串去解码decode,变成Unicode
    但是将该字符串解码变成Unicode期间,却出错了
    (2)所用的是何种编码

    好的,接着看上面的错误:

    ‘gbk’ codec can’t decode
    使得错误信息更加明显了:

    你此处,要将字符串解码为Unicode,是以gbk编码的方式去解码(该字符串变成Unicode)的
    但是此处通过gbk的方式,却无法解码(can’t decode )
    注:此处的codec,意思是:编解码(器),是Python内部的模块,用来编码或解码(字符串)的
    (3)错误位置

    bytes in position 2-3

    此处的信息,后续一般也很少用到。

    有时候会用于定位具体错误的位置。

    此处暂且忽略。

    (4)错误的细节错误类型

    illegal multibyte sequence

    翻译为中文为:

    非法的,多字节,序列

    简单说就是:

    没法(解码)了。

    【原因及解决办法】

    好了,针对于上面所分析出来的信息:

    将一个字符串,通过gbk的方式,去解码,想要获得Unicode字符串,结果出错了

    我们来说说原因和解决办法:

    此种错误,有几种可能:
    (1)要处理的字符串本身不是gbk编码,但是你却以gbk编码去解码
    比如,字符串本身是utf-8的,但是你却用gbk去解码utf-8的字符串,所以结果不用说,则必然出错

    则必然会出现这类的错误,说是,用gbk的方式去解码字符串,想要获得Unicode字符串,但是结果却解码出错了

    解决办法:

    如果你确定当前字符串,比如抓取网页通过charset=utf-8,已经确定html的字符串是utf-8的,

    则可以直接去通过utf-8去解码。

    相关参考内容:

    详解抓取网站,模拟登陆,抓取动态网页的原理和实现(Python,C#等)

    中的:

    【整理】关于HTML网页源码的字符编码(charset)格式(GB2312,GBK,UTF-8,ISO8859-1等)的解释

    而如果本身对于所处理的字符串,不太清楚是什么编码类型的,可以尝试去通过chardet等模块,去检测看看:

    【教程】如何用Python中的chardet去检测字符编码类型

    然后搞清楚了,确定了,字符串是什么类型,然后再去解码。

    提示:

    关于字符串编码的类型,作为背景学习知识,也应该去了解一下。

    这样对于以后处理字符串方面,会更有帮助。

    (2)你没有主动的去将字符串编码为对应的Unicode,但是结果也报上面的UnicodeDecodeError的错误

    这个情况,最常见的,就是我之前在:

    【总结】Python 2.x中常见字符编码和解码方面的错误及其解决办法

    所整理过的:

    “Python中,打印字符串时,字符串本身的编码,与输出终端中所用编码不匹配”

    此处不再赘述,只简要再说一下:

    如果你本身拿到的是utf-8等,非gbk编码的字符串,然后用print去打印出来

    在windows系统就是输出到cmd中

    而cmd中,(对于多数中国人所用的是中文的系统)默认字符编码是gbk

    从而导致此种现象:

    python要将utf-8编码的字符串,在gbk的cmd的中打印出来

    所以先要去尝试,用gbk的编码,解码为Unicode然后再打印出来

    结果就出现此处的错误了。

    详细解释,还是参见上面的教程。

    其中还有示例代码的。

    (3)处理的字符的确是gbk的,但是其中夹杂的部分特殊字符,是gbk编码中所没有的
    如果有些特殊字符是GB18030中有的,但是是gbk中没有的。
    则用gbk去解码,去所不支持的字符,也比如会出错。
    所以,此种情况,可以尝试用和当前编码(gbk)所兼容的但所包含字符更多的编码(gb18030)去解码,或许就可以了。

    提示:

    如果对于GBK,GB18030,以及GB2312不了解,则可参考:

    字符编码简明教程

    另外:

    如果遇到其他的,类似此中错误的,比如:

    UnicodeEncodeError: 'gbk' codec can't encode character u'\u3232' in position 0: illegal multibyte sequence
    等类型的错误,你就可以按照上述的思路,去分析,错误的现象,原因,然后通过自己,就可以找到解决办法了。

    注:

    其他和这类错误相关的,也还有一些可以参考的:

    【总结】静态网页抓取,动态网页抓取,模拟登陆的注意事项和心得

    中的:“返回的html内容是乱码”

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-18 11:04 , Processed in 0.061137 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表