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
版權宣告:本文為博主原創文章,轉載請附上博文連結!