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. 怎样快捷获取元素节点head

    1. 使用: document.head document.head.nodeName; // "HEAD" 2. 使用: document.getElementsByTagNam ...

  2. beego 参数配置

    详细配置请参考:https://godoc.org/github.com/astaxie/beego#pkg-constants. App配置 AppName 应用名称,默认是 beego.通过bee ...

  3. Web API 接口版本控制 SDammann.WebApi.Versioning

    前言 在设计对外 Web API 时,实务上可能会有新旧版本 API 并存的情况,例如开放 Web API 给厂商串接,但同一个服务更新版本时,不一定所有厂商可以在同一时间都跟着更新他们的系统,但如果 ...

  4. HDU5124lines题解-堆+贪心的一个新方法

    题目链接 https://cn.vjudge.net/problem/HDU-5124 胡扯 感觉说新方法好像有点不太好,但是翻了十几篇博客都是清一色离散化之类的... 为什么会做这道题呢?因为前几天 ...

  5. mybatis基础小结

    1.JDBC是怎么访问数据库的?答:JDBC编程有6步,分别是1.加载sql驱动,2.使用DriverManager获取数据库连接,3.使用Connecttion来创建一个Statement对象 St ...

  6. ubuntu目录结构(转)

    /:根目录,一般根目录下只存放目录,不要存放文件,/etc./bin./dev./lib./sbin应该和根目录放置在一个分区中 /bin:/usr/bin:可执行二进制文件的目录,如常用的命令ls. ...

  7. js之数据类型(对象类型——构造器对象——正则)

    正则(regular expression)描述了一种字符串的匹配式.一般应用在一些方法中,用一些特殊的符号去代表一些特定的内容,对字符串中的信息实现查找,替换,和提取的操作.js中的正则表达式用Re ...

  8. BFC渲染机制

    BFC(block formatting context):块级格式化上下文(实际就是一个隔离罩) W3C CSS2.1 规范中的一个概念.它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元 ...

  9. c# 将datatable中的数据保存到excel文件中

    using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Lin ...

  10. MSP432 BSL流程(UART)

    升级流程 PC程序会解析脚本中的命令,根据命令码做相应的操作.数据来自于命令后的文件(当前目录下的数据文件) # cat script_P4xx_uart.txt LOG //记录日志 MODE P4 ...