十五年测试老手,长期负责WEB\APP 项目测试,目前主要负责团队管理工作。

【转】使用python爬虫抓站的一些技巧总结:进阶篇

上一篇 / 下一篇  2011-04-06 23:43:03 / 个人分类:python

以前写过一篇使用python爬虫抓站的一些技巧总结,总结了诸多爬虫使用的方法;那篇东东现在看来还是挺有用的,但是当时很菜(现在也菜,但是比那时进步了不少),很多东西都不是很优,属于”只是能用”这么个层次。这篇进阶篇打算把“能用”提升到“用得省事省心”这个层次。51Testing软件测试网r x&}{ Z/ak$l2q
一、gzip/deflate支持51Testing软件测试网3|`d|6\9d9jM
51Testing软件测试网#P;n Fjc(p*J
现在的网页普遍支持gzip压缩,这往往可以解决大量传输时间,以VeryCD的主页为例,未压缩版本247K,压缩了以后45K,为原来的1/5。这就意味着抓取速度会快5倍。
X Am0VI;Q'VzZ^z0
[8Y|s KWup4~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\,G1e x ?!I _
    return req
xAKb!\8X4K0 51Testing软件测试网O0aBE)J/o&K"BeA%H
  # decode51Testing软件测试网VIw7Ac O
  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 Z c)Qo!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":
n.kMv\0        gz = StringIO( deflate(resp.read()) )
E6r}/?HV0        resp = urllib2.addinfourl(gz, old_resp.headers, old_resp.url, old_resp.code)  # 'class to add info() and51Testing软件测试网:yf2h%Q(F ]m[^
        resp.msg = old_resp.msg
P tvZo0    return resp51Testing软件测试网a+dj/M nCp"M1d1@
 51Testing软件测试网&u$TL F1Z3x;}1c
# deflate support
%OO%_{T0import zlib51Testing软件测试网.}(ds9ma*h
def deflate(data):   # zlib only provides the zlib compress format, not the deflate format;
%G/@x9[^+dr l0  try:               # so on top of all there's this workaround:51Testing软件测试网T#gL#wQ.j
    return zlib.decompress
G0Y@r W!~|.U051Testing软件测试网8Kb;LbXE0nv;k
           51Testing软件测试网6{1Mi9g0]*}9f J"g7v(i

TAG: Python python

 

评分:0

我来说两句

Open Toolbar