python讀寫csv時中文亂碼問題解決辦法


https://www.cnblogs.com/shengulong/p/7097869.html

 

參考1

參考2

參考3

CSV是英文Comma Separate Values(逗號分隔值)的縮寫,顧名思義,文檔的內容是由 “,” 分隔的一列列的數據構成的,可以使用excel和文本編輯器等打開。CSV文檔是一種編輯方便,可視化效果極佳的數據存儲方式

1、python讀寫、追加csv方法:

‘r’:只讀(缺省。如果文件不存在,則拋出錯誤)
‘w’:只寫(如果文件不存在,則自動創建文件)
‘a’:附加到文件末尾(如果文件不存在,則自動創建文件)
‘r+’:讀寫(如果文件不存在,則拋出錯誤)

復制代碼
1 import csv,os
2 if os.path.isfile('test.csv'):
3     with open("test.csv","r") as csvfile:
4         reader = csv.reader(csvfile)
5         #這里不需要readlines
6         for line in reader:
7             print line
復制代碼
復制代碼
import csv

#python2可以用file替代open
#不存在則會創建文件
with open("test.csv","w") as csvfile: 
    writer = csv.writer(csvfile)

    #先寫入columns_name
    writer.writerow(["index","a_name","b_name"])
    #寫入多行用writerows
    writer.writerows([[0,1,3],[1,2,3],[2,3,4]])
復制代碼
復制代碼
import csv

#python2可以用file替代open
#不存在則會創建文件
with open("test.csv","a") as csvfile: 
    writer = csv.writer(csvfile)

    #先寫入columns_name
    writer.writerow(["index","a_name","b_name"])
    #寫入多行用writerows
    writer.writerows([[0,1,3],[1,2,3],[2,3,4]])
復制代碼

2、excel打開csv文件,可以識別編碼“GB2312”,但是不能識別“utf-8”,數據庫里的字符串編碼是utf-8.因此:

當從csv讀取數據(data)到數據庫的時候,需要先把GB2312轉換為unicode編碼,然后再把unicode編碼轉換為utf-8編碼:data.decode('GB2312').encode('utf-8')

當從數據庫讀取數據(data)存到csv文件的時候,需要先把utf-8編碼轉換為unicode編碼,然后再把unicode編碼轉換為GB2312編碼:data.decode('utf-8').encode('GB2312')

3、decode('utf-8')表示把utf-8編碼轉換為unicode編碼;encode('utf-8')表示把unicode編碼轉換為utf-8編碼

4、Unicode只是一個符號集,它規定了符號的二進制代碼,卻沒有規定二進制代碼如何存儲

5、可以使用python的編碼轉換模塊:codecs

 

復制代碼
 1 python unicode文件讀寫:
 2 
 3 #coding=gbk
 4 import codecs
 5 
 6 f = codecs.open('c:/intimate.txt','a','utf-8')#這里表示把intimate.txt文件從utf-8編碼轉換為unicode,就可以對其進行unicode讀寫了
 7 f.write(u'中文')#直接寫入unicode
 8 s = '中文'
 9 f.write(s.decode('gbk'))#先把gbk的s解碼成unicode然后寫入文件
10 f.close()
11 
12 f = codecs.open('c:/intimate.txt','r','utf-8')
13 s = f.readlines()
14 f.close()
15 for line in s:
16     print line.encode('gbk')
復制代碼

 

6、python代碼文件的編碼

py文件默認是ASCII編碼,中文在顯示時會做一個ASCII到系統默認編碼的轉換,這時就會出錯:SyntaxError: Non-ASCII character。需要在代碼文件的第一行或第二行添加編碼指示:

  1. # coding=utf-8 ##以utf-8編碼儲存中文字符
  2. print ‘中文’像上面那樣直接輸入的字符串是按照代碼文件的編碼來處理的,如果用unicode編碼,有以下2種方式:
    1. s1  = u’中文’ #u表示用unicode編碼方式儲存信息
    2. s2 = unicode(‘中文’,’gbk’)

unicode是一個內置函數,第二個參數指示源字符串的編碼格式。

decode是任何字符串具有的方法,將字符串轉換成unicode格式,參數指示源字符串的編碼格式。

encode也是任何字符串具有的方法,將字符串轉換成參數指定的格式。

python字符串的編碼

用 u’漢字’ 構造出來的是unicode類型,不用的話構造出來是str類型

str的編碼是與系統環境相關的,一般就是sys.getfilesystemencoding()得到的值

所以從unicode轉str,要用encode方法

從str轉unicode,所以要用decode

例如:

# coding=utf-8   #默認編碼格式為utf-8

s = u'中文' #unicode編碼的文字
print s.encode('utf-8')   #轉換成utf-8格式輸出 
print s #效果與上面相同,似乎默認直接轉換為指定編碼

我的總結:

u=u'unicode編碼文字'
g=u.encode('gbk') #轉換為gbk格式
print g #此時為亂碼,因為當前環境為utf-8,gbk編碼文字為亂碼
str=g.decode('gbk').encode('utf-8')   #以gbk編碼格式讀取g(因為他就是gbk編碼的)並轉換為utf-8格式輸出
print str #正常顯示中文

安全的方法:

s.decode('gbk','ignore').encode('utf-8′) #以gbk編碼讀取(當然是讀取gbk編碼格式的文字了)並忽略錯誤的編碼,轉換成utf-8編碼輸出

因為decode的函數原型是decode([encoding], [errors='strict']),可以用第二個參數控制錯誤處理的策略,默認的參數就是strict,代表遇到非法字符時拋出異常;

如果設置為ignore,則會忽略非法字符;
如果設置為replace,則會用?取代非法字符;
如果設置為xmlcharrefreplace,則使用XML的字符引用。

unicode(str,‘gb2312‘)與str.decode(‘gb2312‘)是一樣的,都是將gb2312編碼的str轉為unicode編碼

7、代碼文件編碼:

我們在.py文件開頭寫的:#-*- coding:utf-8 -*- 聲稱了代碼文件編碼為utf-8,這時候,文件里面書寫字符串都是utf-8編碼的

8、獲得系統編碼:

import sys
print sys.getdefaultencoding()

 9、sys.setdefaultencoding('utf-8')的作用是告訴系統自動解碼,也就是自動完成utf-8到unicode編碼的轉換

復制代碼
#! /usr/bin/env python 
# -*- coding: utf-8 -*- 

import sys 
reload(sys) # Python2.5 初始化后會刪除 sys.setdefaultencoding 這個方法,我們需要重新載入 
sys.setdefaultencoding('utf-8') 

str = '中文' #這是utf-8編碼的字符串
str.encode('gb18030') #轉換為gb18030編碼,因為已經自動解碼,所以不用寫成這種樣式:str.decode('utf-8').encode('gb18030')
復制代碼

 10、字符編碼判斷:

法一:
isinstance(s, str) 用來判斷是否為一般字符串
isinstance(s, unicode) 用來判斷是否為unicode

if type(str).__name__!="unicode":
str=unicode(str,"utf-8")
else:
pass
法二:
Python chardet 字符編碼判斷
使用 chardet 可以很方便的實現字符串/文件的編碼檢測。尤其是中文網頁,有的頁面使用GBK/GB2312,有的使用UTF8,如果你需要去爬一些頁面,知道網頁編碼很重要的,雖然HTML頁面有charset標簽,但是有些時候是不對的。那么chardet就能幫我們大忙了。 

chardet實例
>>> import urllib
>>> rawdata = urllib.urlopen('http://www.google.cn/').read()
>>> import chardet
>>> chardet.detect(rawdata)
{'confidence': 0.98999999999999999, 'encoding': 'GB2312'}
>>>chardet可以直接用detect函數來檢測所給字符的編碼。函數返回值為字典,有2個元數,一個是檢測的可信度,另外一個就是檢測到的編碼。 

chardet 安裝
pip install chardet


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM