1. 程式人生 > >python以gzip header請求html資料時,response內容亂碼無法解碼的解決方案

python以gzip header請求html資料時,response內容亂碼無法解碼的解決方案

1. 問題背景

在使用urllib2 module抓取web資料時,如果希望使用如何request header,減少傳輸時資料量。返回的資料,是經過gzip壓縮的。直接按照 content.decode(“utf8”), 解碼會出現異常,並且也無法檢測網頁資料的實際編碼型別。

2. 問題分析

因為http請求中,如果在request header包含”Accept-Encoding”:”gzip, deflate”, 並且web伺服器端支援,返回的資料是經過壓縮的,這個好處是減少了網路流量,由客戶端根據header,在客戶端層解壓,再解碼。urllib2 module,獲取的http response資料是原始資料,沒有經過解壓,所以這是亂碼的根本原因。

3. 解決方案

3.1 Request header移除”Accept-Encoding”:”gzip, deflate”

最快的方案,能直接得到可解碼的資料,缺點是,傳輸流量會增加很多。

3.2 使用zlib module,解壓縮,然後解碼,得到可讀的明文資料。

這也是本文使用的方案

4. 原始碼解析

程式碼如下, 這是一個典型的模擬form表單,post方式提交請求資料的程式碼,基於python 2.7
,

程式碼塊

程式碼塊語法遵循標準markdown程式碼

#! /usr/bin/env python2.7
import sys
import
zlib import chardet import urllib import urllib2 import cookielib def main(): reload( sys ) sys.setdefaultencoding('utf-8') url = 'http://xxx.yyy.com/test' values = { "form_field1":"value1", "form_field2":"TRUE", } post_data = urllib.urlencode(values) cj=cookielib.CookieJar() opener=urllib2.build_opener(urllib2.HTTPCookieProcessor(cj)) headers ={"User-agent"
:"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:36.0) Gecko/20100101 Firefox/36.0", "Referer":"http://xxx.yyy.com/test0", "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language":"en-US,en;q=0.5", "Accept-Encoding":"gzip, deflate", "Connection":"keep-alive", # "Cookie":"QSession=", "Content-Type":"application/x-www-form-urlencoded", } req = urllib2.Request(url,post_data,headers) response = opener.open(req) content = response.read() gzipped = response.headers.get('Content-Encoding') if gzipped: html = zlib.decompress(content, 16+zlib.MAX_WBITS) else: html = content result = chardet.detect(html) print(result) print html.decode("utf8") if __name__ == '__main__': main()

使用本指令碼需要以下環境
- Mac OS 10.9+
- Python 2.7.x

目錄

[TOC]來生成目錄: