Python編程中的字符串編碼轉換問題

2021-03-06 同福編程
1. 介紹
1.1 介紹

福哥今天給大家講講關於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 gbkStr

6. 資料庫數據的編碼

從資料庫裡提取到的數據也是有編碼的,我們一定知道資料庫裡的數據的編碼方式,之後就可以通過直接編碼轉換的方式進行轉換了

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 gbkStr

8. 網頁數據的編碼

使用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

等等這樣的錯誤信息了

免費看文章,自己學技術

每一篇文章都是福哥一個字一個字地敲出來的,都是福哥原創的。

每一篇文章都是經過了福哥的反覆驗證的,都是可以正常使用的。

相關焦點

  • Python合集之Python字符串編碼轉換
    隨著信息技術的發展,各國文字都需要進行編碼,於是出現了GBK、GB2312、UTF-8編碼等。其中GBk和GB2312是我國制定的中文編碼標準,使用一個字節表示英文字母,2個字節表示中文字符。而UTF-8是我國通用的編碼,對全世界所有國家用到的字符都進行了編碼。UTF-8採用一個字節表示英文字符、3個字節表示中文。在Python3.X中。
  • Python高效編程之88條軍規(1):編碼規範、字節序列與字符串
    用程式語言寫代碼是自由的,編譯器不會強制你使用特定的格式編寫程序(只要符合語法,編譯器才不管你呢!)。所以很多程式設計師就會將Python當做自己熟悉的Java、C++等語言來用。不過這些編碼方式真的是最好的選擇嗎?本系列文章將為你揭秘88種在編寫Python代碼中的規則,這些規則將會讓你Python程序更加健壯,運行效率更高。
  • 不得不知道的Python字符串編碼相關的知識
    由於之前不知道編碼的原理,遇到這些情況,就只能不斷的用各種編碼decode和encode。。。。。今天整理一個python中的各種編碼問題的原因和解決方法,以後遇到編碼問題,就不會像莽頭蒼蠅一樣,到處亂撞了。下面的python環境都是在2.7,聽說在3.X中已經沒有編碼的問題了,因為所有的字符串都是unicode了,之後裝個3.X試一下。
  • Python encode()和decode()方法:字符串編碼轉換
    我們知道,最早的字符串編碼是 ASCII 編碼,它僅僅對 10 個數字、26 個大小寫英文字母以及一些特殊字符進行了編碼。ASCII 碼做多只能表示 256 個符號,每個字符只需要佔用 1 個字節。Python 3.x 默認採用 UTF-8 編碼格式,有效地解決了中文亂碼的問題。在 Python 中,有 2 種常用的字符串類型,分別為 str 和 bytes 類型,其中 str 用來表示 Unicode 字符,bytes 用來表示二進位數據。str 類型和 bytes 類型之間就需要使用 encode() 和 decode() 方法進行轉換。
  • Python基礎:數據類型和變量&字符串和編碼
    Python基礎:2.字符串和編碼字符編碼我們已經講過了,字符串也是一種數據類型,但是,字符串比較特殊的是還有一個編碼問題。因為計算機只能處理數字,如果要處理文本,就必須先把文本轉換為數字才能處理。Unicode把所有語言都統一到一套編碼裡,這樣就不會再有亂碼問題了。Unicode標準也在不斷發展,但最常用的是用兩個字節表示一個字符(如果要用到非常偏僻的字符,就需要4個字節)。現代作業系統和大多數程式語言都直接支持Unicode。現在,捋一捋ASCII編碼和Unicode編碼的區別:ASCII編碼是1個字節,而Unicode編碼通常是2個字節。
  • 字符串編碼入門科普
    對於單純做前端或者後端的同學來說,一般很難接觸到編碼問題,因為在同一個平臺上,一般都是使用同一種編碼方式,自然問題不大。但對於寫爬蟲的同學來說,編碼很可能是遇到的第一個坑。這是因為字符串無法直接通過網絡被傳輸(也不能直接被存儲),需要先轉換成二進位格式,再被還原。因此凡是涉及到通過網絡傳輸字符的地方,通常都容易遇到編碼問題。為了方便解釋,我們首先來定義一些概念。
  • Python 2.x 字符編碼終極指南
    但僅了解這篇文章的內容,並不能幫我們在日常編程中躲過一些字符編碼相關的坑,Stackoverflow 上就有大量編碼相關的問題,比如 1,2,3。本文首先嘗試對編碼、解碼進行一個宏觀、直觀的解讀,然後詳細來解釋 python2 中的str和unicode,並對常見的UnicodeEncodeError 和 UnicodeDecodeError 異常進行剖析。
  • Python: 熟悉又陌生的字符編碼
    (點擊上方公眾號,可快速關注)來源:rapospectrefunhacks.net/2016/11/25/character_encoding/如有好文章投稿,請點擊 → 這裡了解詳情字符編碼是計算機編程中不可迴避的問題
  • Python3 是如何解決棘手的字符編碼問題的?
    題圖:unsplash.comPython3 最重要的一項改進之一就是解決了 Python2 中字符串與字符編碼遺留下來的這個大坑。Python 編碼為什麼那麼蛋疼?已經介紹過 Python2 字符串設計上的一些缺陷:當然這並不算 Bug,只要處理的時候多留心也可以避免這些坑。但在 Python3 兩個問題都很好的解決了。
  • Python字符串函數用法大全
    即將字符串str中的大寫字母轉換為小寫字母,將小寫字母轉換為大寫字母。i lOVE python我愛PYTHON pYTHON Python4. lower()函數描述:將字符串中的所有大寫字母轉換為小寫字母。
  • Python : 熟悉又陌生的字符編碼
    來源:FunHacks連結:https://funhacks.net/2016/11/25/character_encoding/(點擊尾部閱讀原文前往)字符編碼是計算機編程中不可迴避的問題比如,漢字「嚴」的 unicode 編碼是十六進位數 4E25,轉換成二進位有十五位,即 100111000100101,因此至少需要兩個字節才能表示這個漢字,但是對於其他的字符,就可能需要三個或四個字節,甚至更多。這時,問題就來了,如果以前的 ASCII 字符集也用這種方式來表示,那豈不是很浪費存儲空間。
  • 如何正確解決Python中的中文編碼問題?
    編程派微信號:codingpy作者:xianglong原文連結:http://xianglong.me/article/learn-python-1-chinese-encoding/字符串是Python中最常用的數據類型,而且很多時候你會用到一些不屬於標準ASCII字符集的字符,這時候代碼就很可能拋出UnicodeDecodeError:
  • PHP中的字符串、編碼、UTF-8
    」、「字符串轉換」、「PHP字符串的本質」、「多字節字符串」。 字符串的定義和使用  PHP 中能夠通過四種方法設置字符串:  單引號字符串  單引號字符串類似於 Python中的原始字符串,也就是說單引號字符串沒有變量解析功能和特殊字符轉義功能。比如$str='hello\nworld',其中的\n並沒有換行功能。
  • 【python黑魔法】編碼轉換
    我們在使用其他語言的庫做編碼轉換時,對於無法理解的字符,通常的處理也只有兩種(或三種):但是在複雜的現實世界中,由於各種不靠譜,我們處理的文本總會出現那麼些不和諧因素
  • Python拼接字符串的七種方式
    公眾號Python貓, 專注python技術、數據科學和深度學習,力圖創造一個有趣又有用的學習分享平臺。忘了在哪看到一位編程大牛調侃,他說程式設計師每天就做兩件事,其中之一就是處理字符串。相信不少同學會有同感。幾乎任何一種程式語言,都把字符串列為最基礎和不可或缺的數據類型。而拼接字符串是必備的一種技能。今天,我跟大家一起來學習Python拼接字符串的七種方式。
  • 深入剖析go中字符串的編碼問題——特殊字符的string怎麼轉byte?
    為了轉換一下心情, 便有了此篇文章。問題原問題我就不碼字了,直接上圖:看到問題,我的第一反應是ASCII碼值範圍應該是0~127呀,怎麼會超過127呢?go中的字符串是utf8編碼的根據golang官方博客https://blog.golang.org/strings的原文:Go source code is always UTF-8.A string holds arbitrary bytes.
  • 一文看懂Python列表、元組和字符串操作
    序列1 列表列表(List)是Python中非常重要的內置數據類型。列表由一系列元素組成,所有的元組被包含在一對方括號中。列表被創建將後,可以執行添加、刪除、修改操作。列表中可包含任意的Python數據信息,如字符串、數字、列表、元組等。
  • 徹底搞懂python字符編碼,看這篇就夠了!
    ,有時試著試著問題就解決了,有時候怎麼試都沒轍,只有借用 Google,百度各種 大神幫忙,但似乎很少去關心問題的本質是什麼,下次遇到類似的問題重蹈覆轍,那麼你有沒有想過一次性徹底把 Python 字符編碼給搞懂呢?
  • Python 基礎(字符串)
    >>> a = '數據STUDIO'>>> a.center(20, '*')'******數據STUDIO******'兩個字符大小寫轉換方法lower()轉換 str 中所有大寫字符為小寫,返迴轉換為小寫的字符串的副本
  • Python 編碼為什麼那麼蛋疼?
    作者:劉志軍,6年+Python使用經驗, 高級開發工程師,目前在網際網路醫療行業從事Web系統構架工作個人公眾號:Python