Headers設置之Accept-Encoding
本文是headers系列文章第三篇
前兩篇如下
- Headers之User-Agent設置
- Headers之Referer設置
我們請求網頁時,伺服器返回給我們的信息有時是經過壓縮的,只有解壓才能獲取我們想要的數據。我們先來看下面兩張圖
關註上面兩個值
- response headers中的content-encoding
- request headers 中的accept-encoding
content-encoding是指網頁使用了哪種壓縮方式傳輸數據給你,accept-encoding表示你發送請求時告訴伺服器,我可以解壓這些格式的數據。
二者的關係是,對方網頁會根據你發送的accept-encoding來決定用什麼格式(content-encoding)傳給你。
accept-encoding而無法獲取數據的情況我個人是沒有遇到過的,只是看到網上一些文章提到了這一點,於是研究了一下。我發現那些文章多是基於urllib庫進行的請求,而我使用requests庫請求他們請求的網頁,並不會出現他們遇到的問題。
他們的問題在於:用urllib請求時如果帶有accept-encoding,則返回的內容是經過壓縮的,而urllib還不會自動解壓縮,此時我們如果以為獲得的是源代碼本身然後去解碼、處理,就會報錯。所以這種情況下,拿到的是壓縮數據,可以使用python庫進行解壓,然後再解碼、解析網頁。另一種方法是請求時將headers中的accept-encoding欄位去除掉,即告訴網頁我不支持壓縮數據,於是網頁就會把源代碼本身的數據傳送給你,這樣不涉及解壓的問題,但是網路傳輸消耗的流量就會比傳輸壓縮內容消耗的流量大得多。
而requests與urllib的區別在於,即使返回的是壓縮數據,requests也會自動解壓縮。
接下來,為了讓讀者對此有一個更直觀的認識,我們用requests庫來演示一下content-encoding和accept-encoding值的變化情況
首先,默認情況
import requestsheaders = { user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36}r = requests.get(https://zhuanlan.zhihu.com/python-programming, headers = headers)
來看看沒有設置Accept-Encoding時默認兩個值分別是什麼
>>> r.request.headers[Accept-Encoding]gzip, deflate>>> r.headers[Content-Encoding]gzip
說明默認情況下,requests告訴對方網頁,我支持gzip和deflate這兩種壓縮方式,於是網頁響應時使用gzip方式壓縮數據傳輸給我們。
這時我們來看一下返回的數據是否正確
>>> r.text[:300]<!doctype html>
<html lang="zh" data-theme="light"><head><meta charset="utf-8"/><title data-react-helmet="true">python編程</title><meta name="renderer" content="webkit"/><meta name="viewport" content="width_=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/><meta name="force-renderi
數據是正確的,說明requests內部自己解壓了。
現在改一下請求
headers = { Accept-Encoding: , user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36}r = requests.get(https://zhuanlan.zhihu.com/python-programming, headers = headers)>>> r.headers[Content-Encoding]Traceback (most recent call last): File "<stdin>", line 1, in <module> File "C:Program FilesAnaconda3libsite-packages
equestsstructures.py", line 54, in __getitem__ return self._store[key.lower()][1]KeyError: content-encoding
我們可以看到響應里沒有content-encoding欄位了,說明返回數據時沒有經過壓縮
源代碼返回正常
>>> r.text[:300]<!doctype html>
<html lang="zh" data-theme="light"><head><meta charset="utf-8"/><title data-react-helmet="true">python編程</title><meta name="renderer" content="webkit"/><meta name="viewport" content="width_=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/><meta name="force-renderi
那些因為解壓縮而報錯,並用python解壓的文章可以看下面
- Python 筆記六:入門爬蟲坑--網頁數據壓縮(python deflate gzip)
- Python爬取網頁Utf-8解碼錯誤及gzip壓縮問題的解決辦法
- 如何確定一個python爬取得網頁是否是被壓縮的?
- python以gzip header請求html數據時,response內容亂碼無法解碼的解決方案
專欄信息
專欄主頁:python編程
專欄目錄:目錄
爬蟲目錄:爬蟲系列目錄
版本說明:軟體及包版本說明
推薦閱讀:
※python爬蟲——下載ted視頻
※beautifulsoup+json抓取stackoverflow實戰
※使用requests+beautifulsoup爬取你想要的數據
※python爬取QQ音樂