1. 程式人生 > >爬蟲rewquests爬去網頁亂碼問題

爬蟲rewquests爬去網頁亂碼問題

響應頭 直接 爬蟲 rfc 頁面 一個bug 區別 使用 -type

requests在爬取網頁時候時候中文顯示亂碼

import requests
url = ‘http://www.neihan8.com/wenzi/index_2.html
res = requests.get(url)
res.encoding #獲取res的編碼格式
res.headers #獲取Content-Type內容
res.apparent_encoding #獲取網頁正確的編碼格式 html
= res.text# 返回的結果是處理過的Unicode類型的數據 print(res)
print(res.encoding)#獲得網頁源碼的格式 打印顯示 ISO-8859-1

第一個問題是,為什麽會有ISO-8859-1這樣的字符集編碼?

iso-8859是什麽? 他又被叫做Latin-1或“西歐語言” . 對於我來說,這屬於requests的一個bug,在requests庫的github裏可以看到不只是中國人提交了這個issue. 但官方的回復說是按照http rfc設計的。

下面通過查看requests源代碼,看這問題是如何造成的 !

requests會從服務器返回的響應頭的 Content-Type 去獲取字符集編碼,如果content-type有charset字段那麽requests才能正確識別編碼,否則就使用默認的 ISO-8859-1. 一般那些不規範的頁面往往有這樣的問題. 現在一般的Content-Type 是‘text/html‘。所以現在一般讀取源碼以後都是用‘ html = res.text‘ 格式讀取。但是也可用通過html = res.content來獲取返回的源碼。

第二個問題, 那麽如何獲取正確的編碼?

requests的返回結果對象裏有個apparent_encoding函數, apparent_encoding通過調用chardet.detect()來識別文本編碼. 但是需要註意的是,這有些消耗計算資源.
至於為毛,可以看看chardet的源碼實現.

第三個問題,requests的text() 跟 content() 有什麽區別?

requests在獲取網絡資源後,我們可以通過兩種模式查看內容。 一個是res.text,另一個是res.content,那他們之間有什麽區別呢?

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

requests中文亂碼解決方法有這麽幾種

1、由於content是HTTP相應的原始字節串,可以根據headers頭部的charset把content decode為unicode,前提別是ISO-8859-1編碼.

r.encoding   # ‘gbk‘
print r.content.decode(r.encoding)

 2、另外有一種特別粗暴方式,就是直接根據chardet的結果來encode成utf-8格式.

r  = requests.get(‘http://item.jd.com/1012551875.html‘)
r.apparent_encoding     #   ‘GB2312‘
r.encoding   # ‘gbk‘
r.content.decode(r.encoding).encode(‘utf-8‘)# 問題 r.encoding和r.apparent_encoding什麽區別????

 如果在確定使用text,並已經得知該站的字符集編碼時,可以使用 r.encoding = ‘xxx’ 模式, 當你指定編碼後,requests在text時會根據你設定的字符集編碼進行轉換.

>>> import requests
>>> r = requests.get(‘https://up.xiaorui.cc‘)
>>> r.text
>>> r.encoding
‘gbk‘
>>> r.encoding = ‘utf-8‘

  

爬蟲rewquests爬去網頁亂碼問題