Python 如何將 Unicode 轉換到漢字?

在網上搜索了一圈仍然沒有找到想要的答案,我用split 分割出了含有Unicode代碼的部分,然而那部分無法轉換到漢字。例如

foo = "name : u59dau6668"
bar = foo[7:len(foo)] # To get "u59dau6668"
print bar

然後 bar 無論如何都沒辦法轉換到漢字,求問這裡怎麼辦,試過 unicode, decode, encode...

最好能給出 python2 以及 python3 的解法。


如果不方便手動加u的話,像這樣


前面加個u


Python2配windows簡直婊子配狗,遇到編碼問題我都是抱著吃屎的心態去解決的。。。。你這全都是unicode還沒啥,列印不出來估計是因為你用的dos窗口,默認編碼是gbk。如果出現了看不懂的編碼格式以及奇怪的符號,推薦beautifulsoup庫的damn。。。應該是這麼叫的,專門治療各種編碼問題
好吧,題主貌似還問了python2和3的處理,我就貼圖不說話......
先是python2.7,用的ipython終端,比較炫酷= =

然後是python3.4= =你感受一下


decode("unicode-escape")


回答這個問題,需要我們理清python中的字元種類及字元編碼方式,這樣就能徹底搞清楚類似的問題,我們一個一個的來介紹。

我用我專欄里的一篇文章來仔細講講:

專欄鏈接:給妹子講python,歡迎大家關注,提意見!

先來介紹一下Python中的兩種字元串

Python中有兩種字元串:文本字元串和位元組字元串。其中文本字元串類型被命名為str,內部採用Unicode字符集(兼容ASCII碼),而位元組字元串則直接用來表示原始的位元組序列(用print函數來列印位元組字元串時,若位元組在ascii碼範圍內,則顯示為ascii碼對應的字元,其餘的則直接顯示為16進位數),該類型被命名為bytes。

s = "apple"
b = b"apple"
print(b)
print(type(b))
print(s)
print(type(s))

b"apple"
&
apple
&

再近距離的看看bytes類型位元組字元串,本質上它就是一串單位元組16進位數

b = b"apple"
print(b[0])
print(b[1:])
print(list(b))

97
b"pple"
[97, 112, 112, 108, 101]

然後,再來說說編碼與解碼

從本質上來說,編碼和解碼就是str和bytes這兩種字元串類型之間的互相轉換。

str包含一個encode方法,用於使用特定編碼將其轉換為一個bytes,這稱之為編碼。bytes類包含了一個decode方法,也接受一個編碼作為單個必要參數,並返回一個str,這稱之為解碼。這種轉換操作是顯式的操作,且必須根據數據被編碼時採用的編碼類型進行解碼。

首先說說編碼,即將unicode的str文本字元串轉換為bytes的位元組字元串,可以顯示傳入指定編碼(一般採用utf-8編碼),或使用平台的默認編碼

s = "π排球の"
b1 = s.encode("utf-8")
b2 = s.encode()
print(b1)
print(b2)

b"xcfx80xe6x8ex92xe7x90x83xe3x81xae"
b"xcfx80xe6x8ex92xe7x90x83xe3x81xae"

那麼我們看看,在不寫編碼的時候,平台默認的編碼方式到底是什麼

import sys
print(sys.platform)
print(sys.getdefaultencoding())

win32
utf-8

可以看出平台默認選擇的是utf-8編碼方式。

接下來我們來比較一下unicode、latin-1、ASCII編碼方式的兼容性問題:

首先,非ASCII字元無法使用ASCII編碼轉換成位元組字元串

s = "π排球の"
b = s.encode("ascii")

Traceback (most recent call last):
File "E:/12homework/12homework.py", line 2, in &
b = s.encode("ascii")
UnicodeEncodeError: "ascii" codec can"t encode characters in position 0-3:
ordinal not in range(128)

其次,Latin-1和unicode編碼方式不兼容。

例如,重音字元會在latin-1字符集和unicode字符集中同時存在,但是通過latin-1和unicode編碼方式編出來的位元組流是不一樣的,注意,雖然unicode字符集是包含了latin-1字符集,但是不代表utf-8編碼方式兼容latin-1編碼方式。因為unicode字符集中除了ascii字符集外,都是採用多位元組的編碼方式,而latin-1一律採用單位元組的方式

s = "?è"
print(s.encode("utf-8"))
print(s.encode("latin-1"))

b"xc3x84xc3xa8"
b"xc4xe8"

只有ascii字符集中的字元,三種編碼方式得到的結果才完全一致。對unicode進行編碼的時候,針對常規的7位ASCII文本,由於utf-8以及latin-1編碼方式都是兼容ASCII的,所以結果都是一樣的。

s = "abc"
print(s.encode("utf-8"))
print(s.encode("latin-1"))
print(s.encode("ascii"))

b"abc"
b"abc"
b"abc"

再來談談decode解碼方法

將bytes類型字元串轉換成str類型的unicode文本字元串也是一樣,要麼指定編碼參數,要麼使用平台的默認參數。這個例子中,我們使用的位元組字元串b是通過utf-8編碼方式將"π排球の"編碼而形成的位元組字元串

b = b"xe6x8ex92xe7x90x83"
s1 = b.decode(encoding="utf-8")
s2 = b.decode()
s3 = b.decode(encoding="latin-1")

print(s1)
print(s2)
print(s3)

排球
排球
??』???

值得注意的是,最後一行代碼想通過latin-1解碼位元組字元串,由於位元組字元串是通過utf-8編碼形成,因此這樣解碼形成得到的就是亂碼。

Utf-8編碼是用兩個位元組來表示非ASCII的高128字元,而latin-1則是用一個位元組來一一對應

鋪墊了這麼多,我們再回到問題中來:python如何處理在文本文件讀寫過程中的字元編碼?

當一個文件以文本模式打開的時候,被讀取的二進位存儲數據(也就是存儲的位元組字元串)會自動被解碼(依據顯式提供的編碼名稱或平台默認的編碼名稱),並且將其返回為一個str。寫入文件時,會接受一個str,並且將其傳輸到文件之前自動編碼成位元組字元串。

當一個文件以二進位模式打開時,需要在open方法的模式字元串參數里添加一個b,此時讀取的數據不會以任何方式解碼,而是直接返回其原始內容,即一個bytes對象;寫入文件時,接受一個bytes對象,並且將其傳送到文件中且不進行修改。

在讀取文本文件的時候,如果open函數沒有聲明他們如何編碼,python3會因其所運行的系統而選取默認的編碼方式,默認情況下,python3 期望文件使用 utf-8進行編碼。但由於文件並不總是在同一個系統中被保存和打開,因此會帶來亂碼的風險,所以我們需要顯式的指定編碼。

補充的說明一下,可以很簡單的進行一個分類:處理圖像文件、設備數據流等,可以使用bytes和二進位模式文件處理;而如果要處理的內容實質是文本的內容,例如程序輸出、HTML、國際化文本或CSV或XML文件,則可能要使用str和文本模式文件

例如,我們先把A?BèC用UTF-8編碼後存入utf-8data文件,再來讀取他,具體看看這裡是如何實現的。

s = "A?BèC"

with open("utf-8data","w",encoding="utf-8") as f:
f.write(s)

with open("utf-8data","r",encoding="utf-8") as f:
u_str = f.read()
print(u_str)

A?BèC

這裡提到了文件讀寫的方法後面的章節會詳細介紹,現在知道他是什麼就好了。

以二進位的形式讀取文件。

還有一種方法,我們之前介紹過,文本字元串在存儲在磁碟的時候會編碼形成位元組字元,因此我們也可以先以位元組字元串的形式從文件中讀取位元組字元串,然後再進行解碼。這樣做的原因有二,一種是所接收的可能是非文本數據,如一個圖像文件,另一個潛在原因是無法確定所讀取文本文件的編碼,可能需要依據其他信息再確定

with open("utf-8data", "rb") as f:
byte_str = f.read()

print(byte_str)
print(byte_str.decode(encoding="utf-8"))

b"Axc3x84Bxc3xa8C"
A?BèC

這些內容應該有助於我們更好的在文本處理中使用python.


推薦閱讀:

如何對使用了ssl pinning的APP(如知乎)進行抓包?
scrapy 抓取的中文結果亂碼,請問如何解決?
數據抓取,網站怎麼找到加密轉換的那段js函數?
菜鳥學習網路爬蟲的最佳路線是什麼?
爬蟲相關的技能適合放進簡歷裡面嗎?

TAG:Python | Python3x | 爬蟲計算機網路 |