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

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

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

以前写过一篇使用python爬虫抓站的一些技巧总结,总结了诸多爬虫使用的方法;那篇东东现在看来还是挺有用的,但是当时很菜(现在也菜,但是比那时进步了不少),很多东西都不是很优,属于”只是能用”这么个层次。这篇进阶篇打算把“能用”提升到“用得省事省心”这个层次。
:Q6m\j _p0一、gzip/deflate支持51Testing软件测试网lY X o,O z
51Testing软件测试网[)Ci5Q!zeR,l
现在的网页普遍支持gzip压缩,这往往可以解决大量传输时间,以VeryCD的主页为例,未压缩版本247K,压缩了以后45K,为原来的1/5。这就意味着抓取速度会快5倍。
'w;b2@ A)Nh Du#G051Testing软件测试网*N4co)YI(O*Id.sk7qE
然而python的urllib/urllib2默认都不支持压缩,要返回压缩格式,必须在request的header里面写明’accept- encoding’,然后读取response后更要检查header查看是否有’content-encoding’一项来判断是否需要解码,很繁琐琐碎。如何让urllib2自动支持gzip, defalte呢?51Testing软件测试网6r^;r"|#u&[
51Testing软件测试网n(uZX+mK%zSK
其实可以继承BaseHanlder类,然后build_opener的方式来处理:51Testing软件测试网D+q4NP/k6E"I1Dl Rq

~ Ja4U|R;D0import urllib251Testing软件测试网E.F@*f+vt$V? zo8i#z'D
from gzip import GzipFile
NDr]+f0from StringIO import StringIO
5l;g)P R4j(k s0class ContentEncodingProcessor(urllib2.BaseHandler):51Testing软件测试网H%F-S;APW-[
  """A handler to add gzip capabilities to urllib2 requests """
8]9M2]0I6Ct0 51Testing软件测试网t/^ @gM
  # add headers to requests51Testing软件测试网 CQ,w%DU%R
  def http_request(self, req):51Testing软件测试网W3zY6SRf;D
    req.add_header("Accept-Encoding", "gzip, deflate")
(sS7G%J#p E uN%D3]0    return req
(BK${8M6j#x0 51Testing软件测试网3d^ \gv
  # decode
!y2l^]5h2P.P0  def http_response(self, req, resp):51Testing软件测试网$U#|)r/j'b{%g1?
    old_resp = resp
.? Q-Bl*f!Kn6B K0    # gzip
gL1r,K7V^0    if resp.headers.get("content-encoding") == "gzip":
r]3JlD2b0        gz = GzipFile(51Testing软件测试网 F4Of*Q3^.N3?4py#c
                    fileobj=StringIO(resp.read()),
_(E!g/q/p?2D0                    mode="r"51Testing软件测试网#baN;S/s5t Bm \:S
                  )
cS\ag0        resp = urllib2.addinfourl(gz, old_resp.headers, old_resp.url, old_resp.code)
^&xSI |I1c({Q0        resp.msg = old_resp.msg
0VJLrW NLz:Nn6^0    # deflate
j0c!pI&{0    if resp.headers.get("content-encoding") == "deflate":51Testing软件测试网?sU*QV&RW
        gz = StringIO( deflate(resp.read()) )51Testing软件测试网/b-H BT Fn3v
        resp = urllib2.addinfourl(gz, old_resp.headers, old_resp.url, old_resp.code)  # 'class to add info() and
S+@SW mO0        resp.msg = old_resp.msg
@1w4lE!ox%b m0    return resp
*q w.HFus]-eAz0N `0 
'wV!cV3wTCV t"y0# deflate support
8DK:Rg,ju0import zlib
8ls~(Y#D v#M0def deflate(data):   # zlib only provides the zlib compress format, not the deflate format;51Testing软件测试网c8Fu uX;M^
  try:               # so on top of all there's this workaround:
e Z5AvN"\z2y{0    return zlib.decompress51Testing软件测试网S#U6r)A;L
51Testing软件测试网T+G$oD8a$gm E8Z
           
]F_O Jf5P]g0

TAG: Python python

 

评分:0

我来说两句

Open Toolbar