Python中关于“中文乱码”的问题,现规整如下,并统一回答

同学问:

jacky:我在爬取XX网站信息的时候,中文怎么总是显示的乱码?

jacky:UTF-8与GBK到底是个啥?

jacky:我用的是Mac系统,网上说Python3中默认的编码是UTF-8,可我显示中文时怎么还是乱码?

(一)逻辑导图

Created with Raphaël 2.1.0Python中为什么会出现乱码?解码与编码方式不一致解码与编码具体方式有哪些?实质是什么?Python乱码问题总结

(二)基础铺垫

1.计算机的底层逻辑

Created with Raphaël 2.1.0生活、交易、娱乐、科学研究,都离不开计算机(广义)。无所不能的计算机是怎样实现其功能的?通过计算机语言编码实现的(Python就是其中之一)。那么语言编码又是怎样构成的?计算机语言是由字母,字符和数字组合而成的,不同的排列组合,构成了不同的语言要素,其排列组合的规则就是编码语言的语法接下来,我们要探讨,这些规则是如何制定的?水印:@数据分析-jacky通过0和1的不同组合,若干个0和1,若干种组合,我们制定了编码语言的不同规则为什么只是0和1的组合?这里的0和1,也只是辅助我们标记计算机规则的标记的是什么?标记电路最底层的两种状态:通电和不通电标记电路最底层的两种状态:通电和不通电计算机底层就是电路,现阶段,人类处理电路可能的办法只能是让它通电,或不通电。人类是多么的伟大仅用0和1,就构建了我们现在这个机器智能的世界

2.字符编码

计算机只认二进制的“0”和“1”

ASCII

  • 这个世界的规则就是谁发起,谁定规则。计算机是美国人发明的,在开发计算机的时候,美国人只考虑到了英文的兼容性,并没有考虑包括中文在内的其他语言。

  • 英语构成计算机最底层的元素就是:26个英语字母,加上特殊字符,加上数字。

(1)发明计算机时,字符编码使用的是ascii码,包括Python2默认的字符编码就是ascii码(Python3默认使用的是UTF-8,详见下文);

(2)ascii码为1字节(8位)

  • 8位二进制(例如:01010101)有多少种排列组合? 28 =256种可能

  • 对于英文来说,8位二进制足够用了,所有python2还默认ascii码也不足为奇。

Unicode(万国码)

  • 全球化和科技共享,让计算机的开发者认识到,要开发一种各国语言都能兼容的编码,就有了unicode,也叫万国码。

(1)unicode 包含各国所有的语言文件和符号,对于中文来说,8位已经不够用了,unicode规定:一个中文汉字最少用3个字节来表示。

  • 一个字节是8位,1byte=8bit=01010101,一个汉字最少有2的24次方种组合

(2)Python中可以用bin函数将十进制转化为二进制

bin(82)
'0b1010010' #b表示的R是二进制

(3)万国码的弊端

  • 占内存和硬盘

    • 用英文字母R举例:如何用ascii码表示为’0b1010010’,如何用万国码表示为

      ‘000000000b1010010’,因为万国码,最少是2个字节,与ascii相比,万国码白白浪费了1个字节的空间。
  • 针对unicode的弊端,如今的开发者,又对unicode进行了精简,开发了UTF-8编码

(4)特别说明(读完下文在回来看,就好理解了)

  • Unicode是Python的内部编码,也是编码和解码的中间编码。

UTF-8编码

  • UTF-8编码是对unicode 的一个再加工

    • 对unicode 的编码进行了划分和整理,用8位的就划分为用8位的,不额外在用空间
  • 规则:
    • 英文:8位
    • 欧洲:16位
    • 中文:24位
  • 特别说明:在Unicode编码方式下,才存在 utf-8,utf-16,utf-32的编码方式,这句话对于解释下文的解码与编码特别重要

GBK编码

UTF-8 GBK(@数据分析-jacky)
外国人开发 中国人开发
外国人看不会乱码 外国人看会乱码
一个汉字占3个字节 一个汉字占2个字节

(三)编码与解码

1、基础内容

编码:将字符转化为二进制字节的过程

解码:将二进制字节转化为字符的过程

Created with Raphaël 2.1.0字符字符二进制字节二进制字节编码(字符转化为字节的过程)可逆过程解码
Created with Raphaël 2.1.0UTF-8|GBKUTF-8|GBKUnicode中间编码Unicode中间编码encode 编码可逆decode 解码

2、解码和编码的实现方法

(1) 基本逻辑

字符串在Python内部的表示是Unicode编码。

因此在做编码转换时,通常需要以Unicode作为中间编码,即先将其他编码的字符串解码(decode)成Unicode,再从Unicode编码(encode)成另一种编码。

(2) encode与decode

decode的作用是将其他编码的字符串转换成Unicode编码,如str1.decode(‘gbk’),表示将gbk编码的字符串str1转换成Unicode编码;

encode的作用是将Unicode编码转换成其他编码的字符串,如str2.encode(‘UTF-8’),表示将Unicode编码的字符串str2转换成UTF-8编码

因此,使用Python转码的时候一定要先搞明白,字符串str是什么编码,然后decode成Unicode,然后再encode成其他编码。

特别注意:

  • 如果一个字符串已经是unicode了,再进行解码则将出错,因此通常要对其编码方式是否为unicode进行判断:

  • 用非unicode编码形式的string来encode也会报错

(3)支持字符串类型的两种数据模型

python编码有两种数据模型来支持字符串类型 :

  • 一种是str ;
  • 一种是unicode

(四)解决Python乱码的思路

Created with Raphaël 2.1.0乱码?Unicode中转码我们需要的编码方式

代码的实现方式:

decode()->unicode->encode转化为需要的格式

实战案例:

content为从文件中读取的gbk编码的内容,我们通过以上方法输出该内容。

content.decode('gbk').encode('utf-8') 
  • decode方法将content内容转为unicode格式
  • encode方法将unicode格式的数据转化为自己所需要的编码方式。

(五)数据科学领域需注意的问题

作为数据分析(挖掘)师,python与数据库的关联是最常见的,我们用python连接数据库后,将数据写到数据库里的中文有时会是乱码

解决办法是在python文件中加上这样几句话:

conn.set_character_set('utf8')
cur.execute('SET CHARACTER SET utf8')
cur.execute('SET character_set_connection=utf8')
  • conn是数据库的connection,cur是connection的光标cursor

看透“0”、“1”逻辑,轻松解决Python中文乱码的更多相关文章

  1. 解决python中文乱码的方法

    首先需要说明的是,windows下的文件路径,cmd窗口等默认编码都是gbk 但在windows下编写python程序的时候,我们一般采用的编码是utf-8 二者不一致是导致乱码的根本原因! 在pyc ...

  2. Hession集成Spring + maven依赖通讯comm项目 + 解决@ResponseBody中文乱码

    hessian结合spring的demo         hessian的maven依赖: <!-- hessian --> <dependency>         < ...

  3. 解决mysql中文乱码问题?

    mysql是我们项目中非常常用的数据型数据库.但是因为我们需要在数据库保存中文字符,所以经常遇到数据库乱码情况.下面就来介绍一下如何彻底解决数据库中文乱码情况. 1.中文乱码 1.1.中文乱码 cre ...

  4. 彻底解决mysql中文乱码

    mysql是我们项目中非常常用的数据型数据库.但是因为我们需要在数据库保存中文字符,所以经常遇到数据库乱码情况.下面就来介绍一下如何彻底解决数据库中文乱码情况. 1.中文乱码 1.1.中文乱码 cre ...

  5. 彻底解决matplotlib中文乱码问题(转)

    彻底解决matplotlib中文乱码问题 1.环境查看a.系统版本查看[hadoop@p168 ~]$ cat /etc/redhat-releaseCentOS Linux release 7.2. ...

  6. Python 中文乱码matplotlib乱码 (Windows)

    Python解决matplotlib中文乱码问题(Windows) matplotlib是Python著名的绘图库,默认并不支持中文显示,因此在不经过修改的情况下,无法正确显示中文.本文将介绍如何解决 ...

  7. 在Visual Studio Code 中配置Python 中文乱码问题

    在Visual Studio Code 中配置Python 中文乱码问题 方法一:直接代码修改字符集 添加前四行代码 import io import sys #改变标准输出的默认编码 sys.std ...

  8. 解决Eclipse中文乱码 - 技术博客 - 51CTO技术博客 http://hsj69106.blog.51cto.com/1017401/595598/

    解决Eclipse中文乱码 - 技术博客 - 51CTO技术博客  http://hsj69106.blog.51cto.com/1017401/595598/

  9. Ubuntu14.04安装中文输入法以及解决Gedit中文乱码问题

    1 设置中文显示环境 1. 打开System Settings 2. 打开Personal-> Language Support. 会弹出如下对话框,提示你“语言支持没安装完整”. 点击“Rem ...

随机推荐

  1. ButterKnife8.5.1最新版本使用详细步骤

    android studio中使用方法: 1.build.gradle(Modul: app) 添加dependencies{ compile 'com.jakewharton:butterknife ...

  2. Cache的一些总结

    输出缓存 这是最简单的缓存类型,它保存发送到客户端的页面副本,当下一个客户端发送相同的页面请求时,此页面不会重新生成(在缓存有限期内),而是从缓存中获取该页面:当然由于缓存过期或被回收,这时页面会重新 ...

  3. Windows编程 Windows程序的生与死(中)

    <pre style=""><pre class="cpp" name="code">1 #include < ...

  4. WPf ObservableCollection异步调用问题

    当ObservableCollection列表被UI线程占用时,如果在异步线程中调用ObservableCollection,会弹出以下异常: private void Button1_OnClick ...

  5. 3. Java开发环境的搭建:安装JDK,配置环境变量

    1.安装JDK开发环境 下载网站:http://www.oracle.com/ 开始安装JDK: 修改安装目录如下: 确定之后,单击“下一步”. 注:当提示安装JRE时,可以选择不要安装. 2.配置环 ...

  6. jumperver源码理解以及部分修改

    一  admin后台处理以及展示修改    jumpserver 默认不开放admin后台(获取是我没用使用正确的打开方式,) 打开方式 找到程序的入口 urls.py 修改,另外主要看下settin ...

  7. docker container 导入和导出

    目录 docker container 导入和导出 1.前言 2.docker container 的导出 3.docker container 的导入 4.镜像和容器 导出和导入的区别 docker ...

  8. Vmvare 虚拟机固定IP

    首先我们打开虚拟机的虚拟网络编辑器,打开vmvare菜单栏的编辑,选择虚拟网络编辑器.   在打开的网络虚拟器中,会看到相关信息,虚拟机网络类型采用的NAT模式,子网地址是192.168.89.0,虚 ...

  9. 【Day3】1.正则表达式

    1.正则表达式 2.案例 关闭贪婪模式

  10. Linux基础篇之FTP服务器搭建(二)

    上一篇文章说到了搭建FTP匿名用户的访问,接下来讲解一下本地用户的登录. 一.首先先建立一个用户,这里举例:xiaoming,并为其设置密码.  二.修改配置文件. 文件:ftpusers 文件:us ...