? ? ? ?關(guān)于python3的編碼類型均唉,到底是怎么編碼的,一直使我比較疑惑肚菠,在看了網(wǎng)上很多帖子之后舔箭,經(jīng)過自己嘗試與實驗,將自己的總結(jié)寫在下面,一是當(dāng)做一次筆記层扶,二是希望網(wǎng)友們能指正箫章。僅供參考,歡迎指正镜会,謝謝C始拧!戳表!
一桶至、編碼類型
首先,我們需要明白的是計算機(jī)只能識別0扒袖、1這種二進(jìn)制的信息,再說字節(jié)亩码,字節(jié)是計算機(jī)的最小處理單元季率。一個字節(jié)占 8 位,也就是說在計算機(jī)中最小可以處理 8 位的二進(jìn)制數(shù)描沟。同時飒泻,在計算機(jī)上存儲的數(shù)據(jù)也是以字節(jié)為單位的信息,在讀取計算機(jī)上的信息時就是讀取的二進(jìn)制的這些0吏廉、1組成的數(shù)字信息泞遗。
關(guān)于各種編碼類型,常用的有 Ascii席覆、UTF-8史辙、GBK、GB2312以及Unicode 佩伤。我們從Ascii理解他們是怎么來的聊倔。
因為計算機(jī)只能識別二進(jìn)制數(shù),那么如何使計算機(jī)能夠表示字母以及數(shù)字等形式呢生巡?于是想到了建立一個標(biāo)準(zhǔn)碼來翻譯成計算機(jī)能識別的二進(jìn)制數(shù)耙蔑,形成一一對應(yīng),那么輸入一個字符孤荣,那么就能計算機(jī)就可以轉(zhuǎn)變?yōu)槎M(jìn)制甸陌,從而理解。同時盐股,計算機(jī)的最小處理單元是 8 位的二進(jìn)制數(shù)钱豁,因此這個標(biāo)準(zhǔn)碼就占用了 8 位。那么就可以有2的8次方種0疯汁、1組合來表示常用的英文字符寥院,然而標(biāo)準(zhǔn)的 ascii 沒有用滿這 8 位,只用了 7 位涛目。之后又由于制表符秸谢、數(shù)學(xué)符號等里面并沒有凛澎,這張表在 128 個數(shù)的基礎(chǔ)上擴(kuò)展到了 256 個,即?“擴(kuò)展 ascii”估蹄。
在之后塑煎,256 個字符根本無法表示全人類的語言,于是進(jìn)一步擴(kuò)展到了 2 個字節(jié)臭蚁,也是就是2的16次方最铁,這也是中文為什么占兩個字符,而英文字符只需要占一個垮兑,也就產(chǎn)生了GBK等編碼方式冷尉,其實就是中文字與0、1排列組合的映射表使計算機(jī)能夠理解系枪。
在之后由于世界各種的編碼方式不同雀哨,不利于統(tǒng)一交流,于是出現(xiàn)了Unicode私爷、utf8等格式雾棺。
簡單理解就是為了使計算機(jī)處理英文字符,產(chǎn)生了ASCII碼衬浑;為了處理中文字符捌浩,產(chǎn)生了GB2312;為了處理各國字符工秩,產(chǎn)生了Unicode尸饺;為了提高Unicode存儲和傳輸性能,產(chǎn)生了UTF-8助币,它是Unicode的一種實現(xiàn)形式侵佃。
同時,各種編碼方式都對應(yīng)一張0奠支、1組合的二進(jìn)制表馋辈,以此保存信息,單位為字節(jié)倍谜。
二迈螟、python3的編碼
1.python3中文本字符串str和字節(jié)字符串是嚴(yán)格區(qū)分的
首先理解encode(encoding)與decode的定義:
編碼(encode):將Unicode字符串(中的代碼點)轉(zhuǎn)換特定字符編碼對應(yīng)的字節(jié)串的過程和規(guī)則
解碼(decode):將特定字符編碼的字節(jié)串轉(zhuǎn)換為對應(yīng)的Unicode字符串(中的代碼點)的過程和規(guī)則
其次,在python3中顯示的字符串是以unicode進(jìn)行編碼的尔崔,要想轉(zhuǎn)變?yōu)槠渌幋a格式需要對其進(jìn)行encode()編碼答毫,下面請看示例:
由上圖看出:
(1)a是一個字符串,其編碼格式是unicode季春,類型為str字符串洗搂,但是將其進(jìn)行編碼成utf8格式,會出現(xiàn)開頭為b的字節(jié)字符串,其類型為 bytes 故可以發(fā)現(xiàn)兩者是不同的耘拇。
(2)字符串str本身沒有decode這個方法撵颊,因為其本身就是unicode的
(3)將a先解碼在編碼就可以變?yōu)樵瓉淼淖址f明惫叛,在python3中編碼必須經(jīng)過unicode進(jìn)行轉(zhuǎn)化
2.關(guān)于pthon3中對于文件的讀取寫入與儲存
2.1 ? ? 首先定義一個“1.txt”倡勇,內(nèi)容為"哈哈123abc“”,我們來看一下嘉涌,python3是以什么方式讀取寫入文件的妻熊。在這里先說一下如何看txt的編碼格式以及如何修改txt文件的編碼格式,即打開txt ?》 點擊做上方文件 》 點擊另存為 》會出現(xiàn)下方的圖 》可以根據(jù)需要選擇編碼也可以查看編碼類型
注:顯示的為當(dāng)下的編碼類型
2.2 ?其次仑最,我們來看一下讀入文件的編碼方式:
2.2.1在txt為utf8下:
由上圖可知;
(1)所謂亂碼本質(zhì)上是系統(tǒng)(windows默認(rèn))編碼與所提供字符的編碼不一致導(dǎo)致的(windows默認(rèn)ANSI)扔役,ansi在世界由地方不同而不同,在簡體中文Windows操作系統(tǒng)中警医,ANSI 編碼代表 GBK 編碼亿胸;在繁體中文Windows操作系統(tǒng)中,ANSI編碼代表Big5法严;在日文Windows操作系統(tǒng)中损敷,ANSI 編碼代表 Shift_JIS 編碼葫笼,等等深啤。
(2)本人系統(tǒng)是簡體中文Windows,在不明確以什么編碼方式打開下路星,會顯示出亂碼溯街,且亂碼在明確以utf8下是一致的,在表明是gbk下是亂碼一致洋丐。故可知python3是以ANSI讀取存在系統(tǒng)的字節(jié)信息呈昔,然后內(nèi)部自動解碼成unicode。之前說過python是區(qū)分字符unicode和字節(jié)字符(utf8\gbk等)的友绝,在此并不是顯示的字節(jié)類型堤尾,而是字符串str,故encoding的作用是指示python以什么方式解碼所要讀取信息迁客,使之成為unicode郭宝。
注:已有記事本文件(非空),轉(zhuǎn)碼 UTF-8掷漱,復(fù)制到pycharm中粘室,在開始位置打印結(jié)果會出現(xiàn)\ufeff
2.2.2在txt為gbk(ANSI)下:
由上圖可知:
(1)在gbk格式下的txt文件,在不指明編碼方式下就可以正確讀取為字符串卜范,印證了上述看法
(2)在指明為utf8下會報錯衔统,但在上面未報錯,只是出現(xiàn)亂碼,總之不能正確解碼
2.3 ?最后锦爵,來看一下python保存文件的編碼格式(仍以txt為例)
由上圖可知:
(1)默認(rèn)是以ANSI進(jìn)行保存舱殿,在使用encoding()指明編碼方式下公般,會使用指示的方式
(2)說明在python3中吠架,會自動將unicode編碼輸出,encoding的作用很大
2.4 來看一下pythons自己的 .py文件是什么格式
? ? Python程序時會指定工程編碼和文件編碼為UTF-8钓丰,Python代碼被保存到磁盤時就會被轉(zhuǎn)換為UTF-8編碼對應(yīng)的字節(jié)(encode過程)后寫入磁盤迷郑。
????當(dāng)執(zhí)行Python代碼文件中的代碼時枝恋,Python解釋器在讀取Python代碼文件中的字節(jié)串之后,需要將其轉(zhuǎn)換為UNICODE字符串(decode過程)之后才執(zhí)行后續(xù)操作嗡害。
如圖:
由此可知 .py文件是以utf8格式進(jìn)行保存的焚碌,即unicode格式是python在使用時將其他格式解碼生成操作,最后輸出時霸妹,會自動按要求或者默認(rèn)格式編碼十电。
三. 關(guān)于網(wǎng)頁爬取編碼 r.text 與 r.content
對requests獲取的原始數(shù)據(jù),有三種獲取形式:
一個是r.content(萬能叹螟,但須解碼) ? ? ? ? ? 一個是r.text ? ? ? ? ? ? 一個是resp.json()
text -- 審查元素中的全部鹃骂,類型 str (直接表示為unicode)
content -- 以b開頭的審查元素中的全部內(nèi)容,類型 byte(含有編碼形式的罢绽,故有時需要先解碼才能正常顯示文本畏线,圖片則不需要解碼)
json() -- 是針對json格式數(shù)據(jù),可以直接生成字典進(jìn)行數(shù)據(jù)提取
對于網(wǎng)頁數(shù)據(jù)的爬取良价,也是需要編碼格式的:
(1)
這是慕課上嵩老師所寫的一個小的獲取網(wǎng)頁的代碼寝殴,其中需要r.encoding 要正確的獲得。不過現(xiàn)在網(wǎng)頁很多都是utf8寫的明垢,即使不使用encoding蚣常,一般也能正確獲取。
(2)關(guān)于 content 獲取二進(jìn)制的形式痊银,如果需要變?yōu)閠ext 這種獲取的格式抵蚊,可以使用 r.content.decode('utf-8')?
總結(jié):
(1)python以聲明的編碼方式讀取文件字節(jié)(默認(rèn)系統(tǒng)gbk)之后自動解碼為unicode,顯示為字符串,故字符串無decode用法溯革。但是若將字符串編碼為字節(jié)字符串(有編碼格式的)再變?yōu)樵址畡t需先decode再encode
(2) windows系統(tǒng)下贞绳,無論是python還是其他默認(rèn)保存與讀取為gbk格式,除非在保存時指定編碼方式鬓照,encoding=utf8
(3) ?在python中熔酷,從網(wǎng)上獲取r.text類型為str(unicode)無decode,但是r.content是二進(jìn)制形式(帶編碼類型)需先解碼才可以==text
(4)爬蟲中的嘗試編碼格式r.encoding = r.apparent_encoding? 使得返回的內(nèi)容解碼正確(命令要打正確)才能在python中變?yōu)閡nicode
上面如果有什么邏輯錯誤或者理解錯誤的地方豺裆,請大家指正拒秘,感謝:畔浴!躺酒!
參考文獻(xiàn):
https://www.cnblogs.com/zhangqigao/p/6496172.html
https://www.cnblogs.com/laolv/p/7397429.html
https://blog.csdn.net/u014297175/article/details/40507523 ? ? ? ?# 二進(jìn)制押蚤、字節(jié)、編碼的關(guān)系
http://www.runoob.com/python/att-string-encode.html ? ? ? ? ? ? ? ?#python encode的方法
https://www.cnblogs.com/geekard/archive/2012/10/04/python-string-endec.html ?