福哥今天給大家講講關於Python編程中的字符串編碼轉換的問題,這個問題在初學者編程時候會經常遇到,如果要弄清楚這裡面的道道,還是需要好好學習一下的
2. 什麼是編碼所謂編碼就是計算機標記一個漢字(或者是其他國家的文字)對應的數字,在不同編碼裡同樣的一個漢字會對應不同的數字,比如:「福哥」在gbk編碼裡對應的是「205 172 184 163」,在gbk編碼裡一個漢字對應兩個數字,而「福哥」在utf-8編碼裡對應的是「229 144 140 231 166 143」,在utf-8編碼裡一個漢字對應三個數字。
2.1 常用編碼GBK,英文全稱Chinese Internal Code Specification,中文全稱《漢字內碼擴展規範》,所謂的「國標」編碼方式
UTF-8,英文全稱Universal Character Set/Unicode Transformation Format,是比較通用的一種編碼方式,支持幾乎全部國家的語言文字
BIG5,大五碼,是用於繁體漢字的編碼方式
ISO8859-1,單字節編碼,是早期用於英文的網頁的編碼方式
Unicode,統一碼,就是所有國家的語言文字編碼都會有一個方法轉換成Unicode編碼,然後Unicode編碼又可以轉換所有國家的語言文字編碼。所以,python在進行編碼轉換時候都是先用decode轉為unicode,再用encode轉為目標編碼
3. IDLE編碼在編輯器裡定義的字符串常量也是有編碼設置的,這個編碼可以通過腳本「頁頭」進行聲明
3.1 聲明方法在腳本頁頭使用coding指定腳本默認編碼
聲明編碼之後,後面代碼裡出現的常量字符串都會是這個編碼了
4. 系統編碼在程序運行的時候也會有一個編碼設置,這個編碼就是系統編碼,默認的系統編碼是ascii編碼,我們也可以通過sys這個軟體庫來設置它。
在我們使用print命令輸出信息到控制臺的時候,就會嘗試使用系統編碼進行顯示了。而默認是ascii編碼在很多情況下會出現無法解碼的情況
4.1 查看系統編碼導入sys,查看系統編碼
import sys
print sys.getdefaultencoding()4.2 設置系統編碼導入sys,使用reload刷新sys,設置新的系統編碼
import sys
reload(sys)sys.setdefaultencoding("gbk")5. 編碼轉換既然編碼方式有那麼多,我們從不同的媒介上提取到的數據就有可能是不同的編碼方式的,如果要將這些數據統一成我們的代碼使用的默認編碼,就需要學會編碼之間的轉換方法。
5.1 直接編碼轉換在python下可以通過字符串的decode和encode方法進行字符串的編碼轉換操作
通用的技巧就是先通過decode方法將字符串轉成unicode編碼,再通過encode方法將字符串轉為指定的編碼
5.1.1 示例腳本默認是gbk編碼,先轉為utf-8編碼,再轉回gbk編碼
orgStr = "我是福哥"
gbkStr = orgStrprint gbkStr
utf8Str = gbkStr.decode("gbk").encode("utf-8")print utf8Str
gbkStr = utf8Str.decode("utf-8").encode("gbk")print gbkStr6. 資料庫數據的編碼從資料庫裡提取到的數據也是有編碼的,我們一定知道資料庫裡的數據的編碼方式,之後就可以通過直接編碼轉換的方式進行轉換了
7. 示例從資料庫裡查詢出一個欄位的數據,通過直接轉換方法進行編碼轉換
import pymysql
cn = pymysql.connect("192.168.1.168","test","abcdef")cs = cn.cursor()cn.select_db("test")
cs.execute("select * from test")result = cs.fetchone()
utf8Str = result[1]gbkStr = utf8Str.decode("utf-8").encode("gbk")print gbkStr8. 網頁數據的編碼使用selenium模擬瀏覽器獲取網頁上的內容數據也是有編碼的,這種情況下怎麼解決呢?
8.1 示例使用selenium爬取到網頁的內容,通過find命令獲取到的元素上的文字,這個可以直接通過encode進行轉換,因為selenium已經幫助我們把文字轉換成unicode了
from selenium import webdriver
chromeOpts = webdriver.ChromeOptions()chromeOpts.add_argument("--headless")chromeOpts.add_argument("--disable-gpu")chromeOpts.add_argument("--no-sandbox")chrome = webdriver.Chrome(options=chromeOpts)
chrome.get("https://tongfu.net/")
unicodeStr = chrome.find_element_by_css_selector(".topic-title").textgbkStr = unicodeStr.encode("gbk")print (gbkStr)9. IDLE編碼、系統編碼、數據編碼上面我們提到了幾個概念,即:IDLE編碼、系統編碼、數據編碼,它們之間是什麼關係呢?
9.1 IDLE編碼這個又稱之為編輯器編碼,這個編碼是告訴IDLE編輯器我們當前腳本裡聲明的字符串常量的編碼是什麼,如果沒有特別指定的話,默認會是ascii編碼,那樣是無法使用中文的。
9.2 系統編碼有一些軟體包為了使程式設計師開發方便,會自動進行一些數據的編碼轉換,在進行自動轉換編碼的時候所依據的就是系統編碼了。
9.3 數據編碼數據編碼是以變量為單位的,也就是說每一個變量都會有自己的編碼方式,我們在編程的時候需要根據情況對它們進行統一,否則會出現意想不到的問題
10. 字符串輸出如果要使字符串可以正常通過print命令輸出到控制臺上,需要保證IDLE編碼和變量編碼一致,或者變量編碼為Unicode編碼
11. 程序編碼的選擇在編寫python程序的時候選擇不同的編碼是有區別的,我們可以選擇GBK編碼作為程序代碼的編碼,也可以選擇UTF-8編碼作為程序代碼的編碼。
福哥自己選擇的是UTF-8編碼作為程序代碼的編碼,在需要GBK的地方進行轉碼方式實現。
11.1 GBK優先所謂GBK優先就是py程序使用GBK編碼,在需要UTF-8編碼的地方進行手動轉碼。優點是在cmd裡print不會亂碼,缺點是和大部分媒介交互都需要進行轉換(如讀寫資料庫,爬蟲採集網頁)
11.2 UTF-8優先所謂UTF-8優先就是py程序使用UTF-8編碼,在需要GBK編碼的地方進行手動轉碼。優點是在對接各種媒介時候不需要單獨做轉碼處理,缺點是在使用cmd列印的時候或者是異常出錯的時候總是顯示亂碼
12. 常見錯誤12.1 1、未指定IDLE編碼如果沒有指定IDLE編碼,在輸出字符串的時候就會報錯
SyntaxError: Non-ASCII character '\xb8' in file Encoding.py on line 3, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
12.2 2、IDLE和數據編碼不一致如果指定的IDLE編碼和變量編碼不一樣會出現亂碼
13. 總結今天福哥帶著大家學習了字符串編碼的相關知識,後面再處理字符串的時候就會比較清晰怎麼做了!否則,我們會稀裡糊塗地得到關於編碼的報錯信息,諸如:
UnicodeEncodeError: 'ascii' codec can't encode character u'\u3010' in position 0: ordinal not in range(128)
或者
UnicodeEncodeError: 'gbk' codec can't encode character u'\xa9' in position 105046: illegal multibyte sequence
等等這樣的錯誤信息了
免費看文章,自己學技術
每一篇文章都是福哥一個字一個字地敲出來的,都是福哥原創的。
每一篇文章都是經過了福哥的反覆驗證的,都是可以正常使用的。