Encode
by kinsly
本文的内容均基于python3.5
编码一直是python中的大坑,反正我是一直没搞明白,今天在做爬虫的时候,觉得实在是有必要把这些东西整理一下。
什么是编码
简单的来说就是,为了是计算机能够表达不同的文字,人们制定了一些表达字母符号的方法,常见的编码有ASCII,utf-8,汉字常见的有GBK,big5, GB18030。也就是说字符必须编码后才能被计算机所处理,计算机使用的缺省编码方式也就是计算机的内码。具体细节参见UNICODE,GBK,UTF-8区别
Unicode
Unicode是国际组织设计的,包括了世界上所有语言文字的编码方案。那么Unicode只是一种编码方案,并没有规定如何传输,保存编码。所以这就是为什么我们有UTF-8,UTF-7,UTF-16,这几种都是按照unicode设计,不同的具体编码方案。为什么UTF-8是比较常见的呢,是因为UTF-8与ISO-8859-1完全兼容。世界上有两个设计unicode的组织,一个是软件制造商协会,另一个是ISO,所以UTF-8好在能够兼容两个协会的标准。UTF-8是以8位为单元对UCS进行编码。
内码
windows目前已经支持unicode,但是很多文档和程序都是采用特定编码系统。所以我们在使用某些软件的时候,必须将unicode转化为软件支持的编码。如word只支持gb2312,但是好像也能识别unicode。所以如果想输出csv然后用word打开,需要转化为GBK或者GB18030,或者BOMUTF-8。BOM的意思是 Byte order Mark
Python 遇到的问题
UnicodeDecodeError: 'charmap' codec can't decode byte X in position Y: character maps to $<$undefine$>$
这个问题一般来说是在输出的时候,没有对输出的内容进行encode,也就是说计算机内部存储的是unicode,而你需要对其进行encode。
data_df.to_csv('some2.csv',encoding='gb18030')
或者是当你读取unicode保存的文件的时候,如json,你也需要对其进行转码。
with open('a.json',encoding="utf-8") as data_file:
data = json.load(data_file)
UnicodeEncodeError: 'gbk' codec can't encode character '\ufeff' in position 10: illegal multibyte sequence
这种问题往往是你确定的这种编码方式不能识别数据中的某些编码,也不一定是都识别不了,这时可以换一种编码方式,如GB18030之类的
TypeError: a bytes-like object is required, not 'str'
这个好像是,在读写的时候,要把str转化成编码,也就是二进制之类的,需要进行decode
TypeError: Expected String or Unicode
在用pandas读取json会出现,也可能是没有encoding的问题
设置默认encoding方式
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
在python2.7有这样的用法,但是由于有些包默认不一定是utf-8,所以最好还是不要这样写。
核心三原则
- 因为某些原因, python 打开流读取出的是str,所以用你知道的每一种编码把它解码成unicode
- 大概是因为同样的原因,python 的输出也是str, 但是任何一个unicode 只有到要输出的时候才编码成str
- 在此之间,放弃该死的str,忘了它,当你开始处理的时候,确保你的每一个字符串对象都是unicode
这是segmentfault上一篇文章上说的,感谢作者。题目是python编码的意义
不过好像python3已经没有了这种问题
你导入的好几个模块我都没用过....不过能看出来是跳进了python2的encoding大坑了-_-
总之,研究了近百篇文章后我才意识到,破解encoding问题不用那么复杂.
不用''.encode().decode(),也不用sys.setdefaultencode之类
只要你在全文里除了最后输出部分,保证其余每一个字符串全都是unicode格式就行了.
比如直接手写的字符串你好,就要写成u'你好'
在比如,合并数组为字符串时, 就u''.join(arr)
其余的就unicode(s)
最后实在不行了才.decode().encode()
至于codex模块和charset, ccharset等检测字符串编码的,遇到中文一样傻眼,劝别试.
看到另一个回答,这样说,其实也挺有道理,就是不想太纠结,就不要搞太复杂。简单粗暴
decode & encode
通常我们需要decode()与encode()来进行解码与编码
decode encode
str ---------> unicode ---------->str
在python2中,编码之间的转换需要通过unicode,所以假如你想将由gbk编码的字符串转换为utf-8编码,需要先将其转换为unicode,再将其转换为utf-8编码的字符串
u = u'中文' #显示指定unicode类型对象u
str = u.encode('gb2312') #以gb2312编码对unicode对像进行编码
str1 = u.encode('gbk') #以gbk编码对unicode对像进行编码
str2 = u.encode('utf-8') #以utf-8编码对unicode对像进行编码
u1 = str.decode('gb2312')#以gb2312编码对字符串str进行解码,以获取unicode
u2 = str.decode('utf-8')#如果以utf-8的编码对str进行解码得到的结果,将无法还原原来的unicode类型
而在python3中,取消了unicode类型,代替它的是使用unicode字符的字符串类型(str),也就是说,上面的说明可以转化为下面这种形式
decode encode
bytes ---------> str(unicode)------------>bytes
u = '中文' #指定字符串类型对象u
str = u.encode('gb2312') #以gb2312编码对u进行编码,获得bytes类型对象str
u1 = str.decode('gb2312')#以gb2312编码对字符串str进行解码,获得字符串类型对象u1
u2 = str.decode('utf-8')#如果以utf-8的编码对str进行解码得到的结果,将无法还原原来的字符串内容
个人经验
用pandas的函数,
df.to_csv('a.csv', encoding='gbk')
可能会方便一点。或者
df.to_csv('a.csv', encoding='gbk',mode = 'a')
这样可以接着写,类似于append的功能
当然也可以直接csv包中的函数直接保存
with open('m.csv','w',encoding = 'utf-8') as f:
writer = csv.writer(f)
for i in range(1,len(data_total)):
writer.writerow(data_total)
但是这样存储出来的csv用word打开可能是乱码。这时候可以用记事本将其打开,另存为的时候将其编码格式修改为unicode,这样我的word就能识别这些数据
致谢:谢谢汪老师在这个过程之中的帮助。
reference:
- UNICODE,GBK,UTF-8区别 http://www.cnblogs.com/cy163/archive/2007/05/31/766886.html
- python编码的意义 https://segmentfault.com/a/1190000004166137
- https://segmentfault.com/q/1010000004620523
- http://stackoverflow.com/questions/3218014/unicodeencodeerror-gbk-codec-cant-encode-character-illegal-multibyte-sequen
- python encode和decode函数说明 http://www.cnblogs.com/evening/archive/2012/04/19/2457440.html
Encode的更多相关文章
- 防御XSS攻击-encode用户输入内容的重要性
一.开场先科普下XSS 跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS.恶 ...
- HttpPost过程中使用的URLEncoder.encode(something, encode)
URLEncoder.encode("刘美美", "utf-8").toString() = %E5%88%98%E7%BE%8E%E7%B ...
- [LeetCode] Encode String with Shortest Length 最短长度编码字符串
Given a non-empty string, encode the string such that its encoded length is the shortest. The encodi ...
- [LeetCode] Encode and Decode Strings 加码解码字符串
Design an algorithm to encode a list of strings to a string. The encoded string is then sent over th ...
- UnicodeEncodeError: 'ascii' codec can't encode characters in position 820-823: ordinal not in range(128)
真是奇怪了,在itermi里 print(data) 就能直接运行,而在sublime里,就非得写成这样 print(data.encode('utf-8'))
- javascript处理HTML的Encode(转码)和Decode(解码)总结
HTML的Encode(转码)和解码(Decode)在平时的开发中也是经常要处理的,在这里总结了使用javascript处理HTML的Encode(转码)和解码(Decode)的常用方式 一.用浏览器 ...
- URLEncoder.encode 和 URLDecoder.decode 处理url的特殊参数
在使用 url 的 queryString 传递参数时,因为参数的值,被DES加密了,而加密得到的是 Base64的编码字符串,类似于: za4T8MHB/6mhmYgXB7IntyyOUL7Cl++ ...
- Python3的decode()与encode()
python3的decode()与encode() Tags: Python Python3 对于从python2.7过来的人,对python3的感受就是python3对文本以及二进制数据做了比较清晰 ...
- Leetcode: Encode String with Shortest Length && G面经
Given a non-empty string, encode the string such that its encoded length is the shortest. The encodi ...
- 字符编码和python .encode().decode()方法
字符编码与encode.decode的问题: 用8个开关表示世界万物 ASCII : American Standard Code for Information Interchange,美国 ...
随机推荐
- web自动化,selenium 无法清空输入框默认值继续输入
有的页面输入框自带默认值,想要修改里面的内容时,先使用clear()再send_keys(),这种方式无法清除只会在默认值后面追加内容,不是我想要的结果 解决方法: 方法一: 先双击,后直接send_ ...
- python3使除法结果为整数
学习python3遇到问题: 今天在学习python时,想利用(121/100)得到的结果为整数 1, 121/100 outout:1.21 但是实际结果是浮点数 1.21 原因:python3后, ...
- uWSGI、WSGI、uwsgi、wsgiref、werkzeug
WSGI WSGI:全称是Web Server Gateway Interface,WSGI不是服务器,也不是python模块.框架.API或者任何软件,只是一种规范,描述web server如何与w ...
- java虚拟机规范(se8)——class文件格式(一)
第四章 class文件格式 本章介绍了java虚拟机的class文件格式.每一个class文件包含一个单独的类或者接口的定义.虽然类和接口不一定都定义在文件中(比如类和接口亦可以通过类加载器直接生成) ...
- Nacos-服务注册地址为内网IP的解决办法
最近在使用Spring Cloud Alibaba这一套微服务解决方案,但是在服务注册的时候,网关死活找不到微服务地址,自己的微服务通过网关怎么也访问不到. 查找原因 仔细一查才发现,网关去访问了一个 ...
- Codeforces Breaking Good
Breaking Good time limit per test 2 seconds memory limit per test 256 megabytes Breaking Good is a n ...
- css字体的样式与分类用法总结
字体的样式 color 设置文本的颜色(前景色) ,它会应用到元素的所有边框,除非被 border-color 或另外某个边框颜色属性覆盖. <style> .box1 { color: ...
- 数据库并发及锁机制及Hibernate锁实现
数据库事务的定义 数据库事务(Database Transaction),是指作为单个逻辑工作单元执行的一系列操作.一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性.一致性.隔离性和持久性) ...
- OkHttp的使用
Download OkHttp3 implementation 'com.squareup.okhttp3:okhttp:3.10.0' 1.1. 异步GET请求 -new OkHttpClient; ...
- go语言从例子开始之Example27.超时处理
超时 对于一个连接外部资源,或者其它一些需要花费执行时间的操作的程序而言是很重要的.得益于通道和 select,在 Go中实现超时操作是简洁而优雅的. Example: package main im ...