1. 程式人生 > >Python中requests.get響應內容中文亂碼解決方案

Python中requests.get響應內容中文亂碼解決方案

Requests原始碼包解析原理
分析requests的原始碼發現,text返回的是處理過的Unicode型的資料,而使用content返回的是bytes型的原始資料。也就是說,r.content相對於r.text來說節省了計算資源,content是把內容bytes返回. 而text是decode成Unicode. 如果headers沒有charset字符集的化,text()會呼叫chardet來計算字符集,這又是消耗cpu的事情。

若reqponse header只指定了type,但是沒有指定編碼(一般現在頁面編碼都直接在html頁面中),查詢原網頁可以看到

 

再找一個標準點的網頁檢視,比如部落格園的網頁部落格園

 

response herders的Content-Type指定了編碼型別。

《HTTP權威指南》裡第16章國際化裡提到,如果HTTP響應中Content-Type欄位沒有指定charset,則預設頁面是'ISO-8859-1'編碼。這處理英文頁面當然沒有問題,但是中文頁面,就會有亂碼了!

 

python中的編碼
字串在Python內部的表示是unicode編碼,因此,在做編碼轉換時,通常需要以unicode作為中間編碼,即先將其他編碼的字串解碼(decode)成unicode,再從unicode編碼(encode)成另一種編碼。

decode的作用是將其他編碼的字串轉換成unicode編碼,如str1.decode(‘gb2312’),表示將gb2312編碼的字串str1轉換成unicode編碼,encode的作用是將unicode編碼轉換成其他編碼的字串,如str2.encode(‘gb2312’),表示將unicode編碼的字串str2轉換成gb2312編碼。

因此,轉碼的時候一定要先搞明白,字串str是什麼編碼,然後decode成unicode,然後再encode成其他編碼。

requests中的編碼
先上結論:之所以request的響應內容亂碼,是因為模組中並沒有正確識別出encoding的編碼,而s.txt的結果是依靠encoding的編碼“ISO-8859-1”解碼出的結果,所以導致亂碼。

所以正確的邏輯應該這樣:

如:

s = requests.get('http://www.vuln.cn')

一般可以先判斷出編碼,比如編碼為gb2312,

str = s.content

可以直接用正確的編碼來解碼。

str.decode('gb2312')

那麼知道這個邏輯,接下來就是需要正確判斷網頁編碼就行了,獲取響應html中的charset引數:

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

但實際上我們並不需要輪子。

因為requests模組中自帶該屬性,但預設並沒有用上,我們看下原始碼:

def get_encodings_from_content(content):

 """

Returns encodings from given content string.

:param content: bytestring to extract encodings from.

"""

charset_re = re.compile(r'<meta.*?charset=["\']*(.+?)["\'>]', flags=re.I)

pragma_re = re.compile(r'<meta.*?content=["\']*;?charset=(.+?)["\'>]', flags=re.I)

xml_re = re.compile(r'^<\?xml.*?encoding=["\']*(.+?)["\'>]')

return (charset_re.findall(content) + pragma_re.findall(content) + xml_re.findall(content))

還提供了使用chardet的編碼檢測,見models.py:

def apparent_encoding(self):

 """The apparent encoding, provided by the lovely Charade library."""

 return chardet.detect(self.content)['encoding']

所以我們可以直接執行encoding為正確編碼,讓response.text正確解碼即可:

response=requests.get('www.test.com')

response.encoding = response.apparent_encoding
--------------------- 
作者:老野_ 
來源:CSDN 
原文:https://blog.csdn.net/feixuedongji/article/details/82984583 
版權宣告:本文為博主原創文章,轉載請附上博文連結!