【转】使用python爬虫抓站的一些技巧总结:进阶篇
上一篇 / 下一篇 2011-04-06 23:43:03 / 个人分类:python
以前写过一篇使用python爬虫抓站的一些技巧总结,总结了诸多爬虫使用的方法;那篇东东现在看来还是挺有用的,但是当时很菜(现在也菜,但是比那时进步了不少),很多东西都不是很优,属于”只是能用”这么个层次。这篇进阶篇打算把“能用”提升到“用得省事省心”这个层次。51Testing软件测试网rx&}{
Z/ak$l2q
一、gzip/deflate支持51Testing软件测试网3|`d|6\9d9jM
51Testing软件测试网#P;n Fjc(p*J
现在的网页普遍支持gzip压缩,这往往可以解决大量传输时间,以VeryCD的主页为例,未压缩版本247K,压缩了以后45K,为原来的1/5。这就意味着抓取速度会快5倍。
XAm0VI;Q'VzZ^z0
[8Y|sKWup4~X6}2u0然而python的urllib/urllib2默认都不支持压缩,要返回压缩格式,必须在request的header里面写明’accept- encoding’,然后读取response后更要检查header查看是否有’content-encoding’一项来判断是否需要解码,很繁琐琐碎。如何让urllib2自动支持gzip, defalte呢?51Testing软件测试网1l8D3tI6G
m ^9cj/pK'Dy$f`4p+Y0其实可以继承BaseHanlder类,然后build_opener的方式来处理:
,V4|/}v:n9?*A051Testing软件测试网7r*~xE5o"D2``
import urllib2
P,ys0w1^:G0p0from gzip import GzipFile
*@A\TuN0from StringIO import StringIO
T?Lu2k2c6]N0class ContentEncodingProcessor(urllib2.BaseHandler):
,bhC-X5e B5I9I?0 """A handler to add gzip capabilities to urllib2 requests """51Testing软件测试网 zT d"Wuxh2_(s
/C0NzseB.R;eqR0 # add headers to requests
e8D,~mI1wZ0 def http_request(self, req):
K!OeW M5PAl0 req.add_header("Accept-Encoding", "gzip, deflate")51Testing软件测试网n\,G1ex ?!I _
return req
xAKb!\8X4K0 51Testing软件测试网O0a BE)J/o&K"BeA%H
# decode51Testing软件测试网VIw7AcO
def http_response(self, req, resp):51Testing软件测试网"\)f7H%v-[2VMn)c
old_resp = resp51Testing软件测试网*R3D'gM z%c\
# gzip51Testing软件测试网;A"w-T"Z ^5b;C
if resp.headers.get("content-encoding") == "gzip":51Testing软件测试网:SZR9aK"H
gz = GzipFile(51Testing软件测试网3hq6X1YCd7[
fileobj=StringIO(resp.read()),
;Zm6b/P `i'S0 mode="r"
/m Zc)Q o!pg$NF0 )51Testing软件测试网z B}D:u6?5GD&d
resp = urllib2.addinfourl(gz, old_resp.headers, old_resp.url, old_resp.code)
,R$co.Sk6~ ]5[u0 resp.msg = old_resp.msg51Testing软件测试网4Y!tVZ6mH-N
# deflate
0?&~2H2sF2BCaR0 if resp.headers.get("content-encoding") == "deflate":
一、gzip/deflate支持51Testing软件测试网3|`d|6\9d9jM
51Testing软件测试网#P;n Fjc(p*J
现在的网页普遍支持gzip压缩,这往往可以解决大量传输时间,以VeryCD的主页为例,未压缩版本247K,压缩了以后45K,为原来的1/5。这就意味着抓取速度会快5倍。
XAm0VI;Q'VzZ^z0
[8Y|sKWup4~X6}2u0然而python的urllib/urllib2默认都不支持压缩,要返回压缩格式,必须在request的header里面写明’accept- encoding’,然后读取response后更要检查header查看是否有’content-encoding’一项来判断是否需要解码,很繁琐琐碎。如何让urllib2自动支持gzip, defalte呢?51Testing软件测试网1l8D3tI6G
m ^9cj/pK'Dy$f`4p+Y0其实可以继承BaseHanlder类,然后build_opener的方式来处理:
,V4|/}v:n9?*A051Testing软件测试网7r*~xE5o"D2``
import urllib2
P,ys0w1^:G0p0from gzip import GzipFile
*@A\TuN0from StringIO import StringIO
T?Lu2k2c6]N0class ContentEncodingProcessor(urllib2.BaseHandler):
,bhC-X5e B5I9I?0 """A handler to add gzip capabilities to urllib2 requests """51Testing软件测试网 zT d"Wuxh2_(s
/C0NzseB.R;eqR0 # add headers to requests
e8D,~mI1wZ0 def http_request(self, req):
K!OeW M5PAl0 req.add_header("Accept-Encoding", "gzip, deflate")51Testing软件测试网n\,G1ex ?!I _
return req
xAKb!\8X4K0 51Testing软件测试网O0a BE)J/o&K"BeA%H
# decode51Testing软件测试网VIw7AcO
def http_response(self, req, resp):51Testing软件测试网"\)f7H%v-[2VMn)c
old_resp = resp51Testing软件测试网*R3D'gM z%c\
# gzip51Testing软件测试网;A"w-T"Z ^5b;C
if resp.headers.get("content-encoding") == "gzip":51Testing软件测试网:SZR9aK"H
gz = GzipFile(51Testing软件测试网3hq6X1YCd7[
fileobj=StringIO(resp.read()),
;Zm6b/P `i'S0 mode="r"
/m Zc)Q o!pg$NF0 )51Testing软件测试网z B}D:u6?5GD&d
resp = urllib2.addinfourl(gz, old_resp.headers, old_resp.url, old_resp.code)
,R$co.Sk6~ ]5[u0 resp.msg = old_resp.msg51Testing软件测试网4Y!tVZ6mH-N
# deflate
0?&~2H2sF2BCaR0 if resp.headers.get("content-encoding") == "deflate":