python3 還原bytes為中文的折騰

2021-03-02 搜狗測試
背景

遇到一個線上問題,需要通過pingback分析用戶的行為。數據組提供一份相關用戶的pingback文件用於分析。但是看pingback文件太痛苦了,於是就想編寫一個腳本處理一下,對針對其中的參數值,替換成其代表的中文含義,方便查看。

需求

由於pingback的log信息都是記錄在linux端的,通常非桌面環境的linux版本都不支持中文顯示,因此導出來的pingback中帶的中文也是非中文的。中文的顯示也是類似這種形式:\xE7\xAD\x89\xE4\xBD\xA0\xE5\x8C\x85\xE5\x85\xBB\xE6\x88\x91,為了方便閱讀,需要把這種類型的字符轉化為中文

實現過程

想要實現這個需求,總共有以下兩個過程:

明確這是啥字符?

怎麼還原這種字符為中文?

一、這是啥字符 ?

經過一番搜索調研,找到這麼一種解釋?

linux默認使用utf-8編碼,而utf-8默認以unicode字符集進行的編碼,此種格式其實是一種utf-8的字節碼[bytes]。如果要還原,需要對其進行utf-8解碼

這次知道是啥了,那就知道要怎麼處理了,python中有很多方法可以編碼、解碼,於是開始第二個過程

二、怎麼還原成中文?

python 3中對字符編碼方面,進行了很大的改進,默認採用了unicode字符集並使用utf-8進行編碼。而且轉換方法很靈活。於是開始實驗:

>>> a = '\xE6\x96\xB0'
>>> a.decode('utf-8')Traceback (most recent call last):  File "<stdin>", line 1, in <module>AttributeError: 'str' object has no attribute 'decode'

似乎有點異常,提示 str 類型沒有decode方法。如上文所說,我們是要對bytes類型的字節碼進行解碼。但提示卻是str類型,看來是犯了一個低級錯誤:我們視覺上看到的只是格式上的字節碼,但實際上它是str類型

>>> type(a)<class 'str'>

所以我們要先把str轉為bytes類型

>>> s = bytes(a, encoding='utf-8')
>>> sb'\xc3\xa6\xc2\x96\xc2\xb0'

好像還有問題,我希望的結果是內容不變,只是把str類型改為bytes類型,但現在結果內容也變了。說明使用bytes()方法進行強制轉換是不行的。繼續在網上查找,發現str的內建encode方法中可以做到保留字符串本身的轉義字符的意義,也就是\x。再次實驗:

>>> s = a.encode('raw_unicode_escape')
>>> s                                 b'\xe6\x96\xb0'                      
>>> type(s)                           <class 'bytes'>                      

這次成功了,繼續之前的解碼

>>> s.decode('utf-8')'新'

已經可以成功的還原成了中文,試試混合其它字符的

>>> m = 'searchResultType=111&word=\xe6\x96\xb0'
>>> m.encode('raw_unicode_escape').decode('utf-8')'searchResultType=111&word=新'

Perfect,下面就是具體的封裝成函數,方便調用了

def get_chinese(str_like_bytes):    
   return str_like_bytes.encode('raw_unicode_escape').decode('utf-8')

到此,問題看來是解決了。下面就是編輯腳本,打開文件,找出要解碼的部分調用方法就可以了

相關焦點

  • Python bytes類型及用法
    bytes 是 Python 3.x 新增的類型,在 Python 2.x 中是不存在的。字節串(bytes)和字符串(string)的對比:字符串由若干個字符組成,以字符為單位進行操作;字節串由若干個字節組成,以字節為單位進行操作。字節串和字符串除了操作的數據單元不同之外,它們支持的所有方法都基本相同。
  • python基礎-bytes和bytearray的用法
    Python中的序列類型有bytes和bytearray。二進位序列類型的用法比較少見,是python中少用的一種序列類型,對於二進位序列類型,大家基本了解即可。bytes二進位序列類型指定長度的零填充字節對象: bytes(3)二進位字符串對象:bytes(b'abc')bytearray二進位數組指定長度的零填充字節對象: bytearray(3)二進位字符串對象:bytearray(b'abc')實例:print(type("ffff
  • Python 3中str與bytes的區分
    【回復「python」,送你十本電子書】  Python 3最重要的新特性大概要算是對文本和二進位數據作了更為清晰的區分。文本總是Unicode,由str類型表示,二進位數據則由bytes類型表示。Python 3不會以任意隱式的方式混用str和bytes,正是這使得兩者的區分特別清晰。
  • Python 的 bytes轉 str
    Python 中的 str、bytes、Unicode1.str是字符數據(如:文本,給人看的),bytes和bytearray是字節數據(如:二進位數據,給計算機看的),它們都是序列,可以進行迭代遍歷。
  • 還在為Python中文亂碼煩惱,老司機給你講講!
    這裡大家 可以先簡單記住一點:python3 Unicode 。UTF-8: 說得官面一點,utf-8是最流行的一種對 Unicode 進行傳播和存儲的編碼方式。明文(str)和字節(bytes)數據之間的轉換關係就是編碼和解碼,從str到bytes叫編碼,用encode命令,從bytes到str叫解碼,用decode命令。需要注意的是,str數據無法進一步decode,bytes數據也無法進一步encode。下面我們來看一個例子,首先看編碼過程:
  • Python3 是如何解決棘手的字符編碼問題的?
    Python 編碼為什麼那麼蛋疼?已經介紹過 Python2 字符串設計上的一些缺陷:當然這並不算 Bug,只要處理的時候多留心也可以避免這些坑。但在 Python3 兩個問題都很好的解決了。str>>> a = "a">>> a'a'>>> type(a)<class 'str'>>>> b = "禪">>> b'禪'>>> type(b)<class 'str'&
  • 每日一課 | Python 3 TypeError:無法將「字節」對象隱式轉換為str
    將Python 2套接字示例轉換為Python 3
  • Python 3 字符串中的 STR 和 Bytes 究竟有什麼區別?
    而Python3嚴格區分文本(str)和二進位數據(Bytes),文本總是Unicode,用str類型,二進位數據則用Bytes類型表示,這樣嚴格的限制也讓我們對如何使用它們有了清晰的認識,這是很棒的。
  • python基礎學習—04字符串與編碼
    三、python源文件編碼3.1  python2.x在python2.x中,python源文件默認使用ASCII碼格式編碼,因此默認情況下是不支持中文的。如果強制輸出中文編譯會報錯,這時如果想在python2.x源文件代碼中輸入中文符,需要使用UTF-8編碼,在源文件開頭處添加:或者3.2  python3.x在python3.x中,python原始碼文件默認統一使用Unicode編碼,默認以UTF-8格式編碼,就可以直接輸出中文字符,不需要在源文件開頭添加上述代碼。
  • Python基礎篇-08 Python版本區別,Python 3和Python 2區別詳解
    公眾號關注「專攻python」,設為「星標」重磅文章,第一時間送達!!
  • Python 與 Unicode
    在我們使用 vim 編輯文本的時候, 所看到的結果其實全都是 vim 將結果輸出到標準輸出的過程, vim 的標準輸出是連著 xterm 的, 所以文本文件的編輯過程就在 xterm 中為我們展現出來.
  • Python 2.x 與 Python 3.x 的區別
    Python 中的除法有兩個運算符,/ 和 // 首先來說下 / 除法:在 python 2.x 中 / 除法就跟我們熟悉的大多數語言,比如 Java、C 差不多,整數相除的結果是一個整數,把小數部分完全忽略掉,浮點數除法會保留小數點的部分得到一個浮點數的結果。在 python3.x 中 / 除法不再這麼做了,對於整數之間的相除,結果也會是浮點數。
  • python編解碼問題詳解
    UTF包含全世界所有國家需要用到的字符(因為來自Unicode)UTF的中文所佔用字節比GBK佔用字節多(UTF佔3個,GBK佔2個),所以如果中文出現比例高的文本,一般用GBK,而不是UTF-8,如中文作業系統,簡體用的是GBK,繁體是BIG5。
  • bytes對象,不可變的字節序列
    為此, Python 額外提供了字節序列對象 —— bytes 。好了,我們已經弄明白 str 對象以 bytes 之間的關係,這兩者是 Python 中最重要的內建對象之一。讀者對 str 對象應該再熟悉不過了,但對更接近底層的 bytes 對象可能涉獵不多。沒關係,經過本節學習,你將徹底掌握它!
  • 如何正確解決Python中的中文編碼問題?
    /usr/bin/python# -*- coding: utf-8 -*-s = '中文's.decode('gb2312') # UnicodeDecodeError: 'gb2312' codec can't decode bytes in position 2-3: illegal multibyte sequenceprint
  • Python3.6新特性官方文檔中文版
    當用戶沒有指定版本(通過命令行參數或配置文件)時,py.exe啟動器以交互方式使用時,不再以Python 2優先於Python 3。 處理shebang行的方式保持不變 - 此處的「python」依舊指Python 2。python.exe和pythonw.exe已標記為長路徑敏感(long-path aware),這意味著260字符路徑限制可能不再適用。
  • 給妹子講python-S01E08理清python中的字符編碼方法
    >2.python中編、解碼方法舉例及過程解析3.unicode、latin-1、ASCII編碼方式的兼容性問題4.讀取二進位文件上一集講清楚字符編碼的基礎概念後,我相信這一集再來介紹python中的字符編碼就會容易的多。
  • 折騰WSL的那些事
    ,如果man手冊也是中文就更好了,所以我們再進行如下操作sudo apt-get install manpages-zhalias cman='man -M /usr/share/man/zh_CN'這樣我們用cman進行查詢就可以得到中文man手冊啦,同時不支持中文的用man仍然可以得到英文手冊這裡部分參考Ubuntu16.04
  • Python3 pickle模塊的使用詳解
    (例如自定義的類的方法,遊戲的存檔等)3、序列化的時候,只是序列化了整個序列對象,而不是內存地址。pickle: 用於python特有的類型和python的數據類型間進行轉換,pickle提供四個功能:dumps,dump,loads,loadpickle可以存儲什麼類型的數據呢?
  • python 3.x 與2.x的區別
    現在不單單是要學python,還在考慮用它做點什麼,這些等後續再說吧,因為看的是python2.x的書籍。用的是python 3.7.所以先把兩者的區別記錄一下,僅限於基礎。python3.x 與2.x的區別1.printprint語句沒有了,取而代之的是print()函數。