python轉碼譯碼
python的編碼轉碼網上有很多文章,如果你不了解這個你可以參考下面了解。
Ned Batchelder 關于python unicode和str的理解,通俗易懂
通過上面我們可以很好的理解python的轉碼譯碼,在這里我想談一下我自己對其的認識吧,我一開始接觸的c語言序列的基本上都是強類型,比如C里面假如我想寫一個函數每個傳人的參數都得是有類型的,但是python弱化了類型這一點,python也是面對對象的,但是他的對象就是雞同鴨講,照貓畫虎就能運行,弱類型適合動態語言,我們不確定下一行代碼輸入的是什么,自從學python起,一直感覺python對類型一直不嚴格,這樣就給了我一種錯覺,只要長得差不多就能一樣的比劃,比如在兩個string,'中國',u'中國',看起來差不多但是如果你把u'中國'存入文件中就會出錯(假如你沒定義編碼規則) UnicodeEncodeError: 'ascii' codec can't encode characters in position 344-351: ordinal not in range(128) unicode字符編碼錯誤,要想理解這個要對unicode字符集和unicode編碼有一定的理解,推薦你讀一下這篇博客字符編碼的知識,python內部使用unicode字符集存貯所以的編碼的字符,為什么要用unicode字符集舉個栗子吧:
A是米國的程序員,他使用asicc編碼的文件上傳了一封郵件, B是中國的程序員他使用gbk編碼的文件上傳了一封郵件, 現在C要用程序同時處理A和B的郵件,有兩種解決方法他把A的文件譯碼再編碼成B的gbk,或者將B的文件譯碼成asicc但是中文無法處理,那么只能使用第一種方法將A的文件編碼成gbk,但是改天D又來啦,他是俄國人,天啊嚕gbk可能沒有把俄語編進去,那腫么辦,我們迫切需要一種編碼可以把所以的字符放進去,所以unicode出現了,Unicode中將字符集按照一定的類別劃分到0~16這17個層面(Planes)中,每個層面中擁有216=65536個字符碼,因此Unicode總共擁有的字符碼,也即是Unicode的字符空間總共有17*65536=1114112,一共有1114112這么多的字符可以用,這下我們不用擔心了吧,太好了這下不用愁了,
python 內部使用unicode字符集作為一個譯碼中轉站,因為他編碼了所以的字符集,只要你能在自己編碼方案上找到自己的字,我就能在unicode字符集找到你的位置,所以使用unicode可以很好的解決多種編碼方案產生的問題(比如gbk,utf-8) 當然其他編碼方案如果想使用unicode解碼成其他的必須同unicode有一一對應關系,不過現在主流的編碼方案如gbk,gb2312,utf-8都是unicode系的。
了解了這些基礎知識就可以知道了為什么存貯u'中國'存不進文件里面去了,因為unicode并不提供給當今字符解析器的方法,就是/u234e一個16進制數字,屏幕上不知道他對應什么圖形,所以python系統要求存進文件的必須是字節流,也就是可以unicode是一種更高級的字符流,這個字符流能存貯當今世界所以定義的字符,但是他只是一個規定字符集合,我們只需要把發現的字符放進去占據一個位置,但是我們不需要考慮屏幕是否認識這個字符,這個字符的存貯由編碼方案負責,如utf-8這些,假如沒有字符編碼方案可以存貯這些,我們雖然在unicode上有這個字符但是我們無法PRint出來,所以我們必須將unicode轉換成普通字符流,有人就會問了,假如我真的沒有找到一個合適編碼方案可以存貯所有語言,我們可以將他編碼成unicode—escape類型,這里我們不多講。
這就可以解釋我們大部分碰到的錯誤unicodedecodeerror和unicodeencodeerror錯誤,都是因為字符編碼方案不了解造成的,網上很多說碰到這種錯誤就encode,decode搞一下就行但是不弄清楚這背后的知識就會犯迷糊。
接下來我談談我遇到的錯誤吧,在爬取http://yjsy.ncu.edu.cn/yjs_showmsg.asp?id=2770這個頁面時(這是一個不規范的頁面沒有設置charset),因為每個spider調用的
response.xpath('//xpath').extract() 選擇器返回的是一個unicode編碼的字符集,但是他是接受的是一個字符流,spider可能調用了 response.body.decode(response.encoding)進行轉碼,但是這個response.encoding有時候會判斷錯誤,比如將我一個gbk編碼的文件判斷成cp1253,這個時候假如我把他解碼成encode成其他編碼方式的話,我們就會得到亂碼,那怎么糾正呢,我們可以這樣干 先將得到的列表中每個content取出來,然后使用content.encode(resonse.encoding)轉碼成原始字符流,現在你可以將它用正確的編碼轉換成unicode了
下面是我github上的關于這個scrapy的項目,在coding_pitch.py文件里面就是對于這個亂碼的處理
新聞熱點
疑難解答