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

免费网页数据抓取采集 python实现一个多线程网页下载器

上一篇 / 下一篇  2011-10-23 14:52:56 / 个人分类:python

文章来源
  • 文章来源:【转载】
  1. #!/usr/bin/envpython   51Testing软件测试网*me7LM(H
  2. # -*- coding:utf-8 -*-     
    u}2V![O}Sf0
  3. import urllib, httplib     
    A3u1^]?N-Yl5d9U0
  4. import thread     
    (S#aG#D d6w0
  5. import time     
    qiW*[KZ0
  6. from Queue import Queue, Empty, Full     51Testing软件测试网sqdeXnS^
  7. HEADERS = {"Content-type": "application/x-www-form-urlencoded",     51Testing软件测试网e3`P/X+Z/U
  8.                         'Accept-Language':'zh-cn',     
    H BPPxk0
  9.                         'User-Agent': 'Mozilla/4.0 (compatible; MSIE 6.0;Windows NT 5.0)',     51Testing软件测试网$EKi'i(R!|5j|7~-Q
  10.                         "Accept": "text/plain"}     51Testing软件测试网n jfmg2c u0i
  11. UNEXPECTED_ERROR = -1     51Testing软件测试网\r!QF%k _/`d+[
  12. POST = 'POST'     
    Ba4Q+d&['nj#G0
  13. GET = 'GET'     51Testing软件测试网uv4Vdsd;dK
  14. def base_log(msg):     51Testing软件测试网H/d"C7o5R
  15.     print msg     51Testing软件测试网%biN l,j
  16. def base_fail_op(task, status, log):     51Testing软件测试网H2{Mk v2R&h$P6Q F
  17.     log('fail op. task = %s, status = %d'%(str(task), status))     51Testing软件测试网1k]L,`z+t ]h
  18. def get_remote_data(tasks, results, fail_op = base_fail_op, log = base_log):     51Testing软件测试网(jI@fC#pU;TU~8^ Y
  19.     while True:     
    &BZy3e!|k NX(BFv0
  20.         task = tasks.get()     
    .sI'h*FR7T:^9`E0
  21.         try:     
    #b4n]'g9Y(G_9M:L_sp0
  22.             tid = task['id']     
    O svxlF0
  23.             hpt = task['conn_args'] # hpt <= host:port, timeout     51Testing软件测试网2W-y;q ^4k7U$Q
  24.         except KeyError, e:     51Testing软件测试网$Obs CT h
  25.             log(str(e))     
    w(qk K3\X$iI0
  26.             continue     
    *G TXaN+K ~C0
  27.         log('thread_%s doing task %d'%(thread.get_ident(), tid))     51Testing软件测试网ac ^B ](l(ytb
  28.         #log('hpt = ' + str(hpt))     
    jqp fx-g;r(ze0
  29.         conn = httplib.HTTPConnection(**hpt)     
    :E f%o%z&p;Bv0
  30.                  
    xyX&U1M.F Q.C0
  31.         try:     51Testing软件测试网4E*u t*VyT6Mj
  32.             params = task['params']     
    6Z:DQ/~/d9s,Q[0
  33.         except KeyError, e:     
    g'g&L? _ B#u0
  34.             params = {}     
    h-h7Q`^-W1wDyy0
  35.         params = urllib.urlencode(params)     51Testing软件测试网Cdd4tc
  36.         #log('params = ' + params)     
    F)?O,T Ny0
  37.             
    6a9H'u)k \~Kk*A&a0
  38.         try:     
    ;{2qOJ ?#}_0
  39.             method = task['method']     51Testing软件测试网K1j-lfr[ ?
  40.         except KeyError:     51Testing软件测试网]LIo.S z!V(p
  41.             method = 'GET'     
    rp \-H/d r0
  42.         #log('method = ' + method)     
    9w? F\S/i I0nt0
  43.             
    J!Z1c*m2Q a&}:KX0
  44.         try:     
    ;|2a,u)P7u+|0
  45.             url = task['url']     51Testing软件测试网~-|Q/rwF-a$v
  46.         except KeyError:     
    4^^2I*Jy8s$P/w0
  47.             url = '/'     51Testing软件测试网V~ I"WvO.y
  48.         #log('url = ' + url)     51Testing软件测试网,U0S'o[|rP,~!wH
  49.             51Testing软件测试网 h{^ L.U:Fp8h2j
  50.         headers = HEADERS     51Testing软件测试网r"W@J%z1y~n)Ym
  51.         try:     51Testing软件测试网+|V\APbW9X
  52.             tmp = task['headers']     
    0w$eDIVV0
  53.         except KeyError, e:     
    r4d*y~_3Gt_NO0
  54.             tmp = {}     51Testing软件测试网X0_U,W(e*CJ
  55.         headers.update(tmp)     51Testing软件测试网_+]!oZ.s,}.IV
  56.         #log('headers = ' + str(headers))     
    #jt&k\4m2YSD8Ey0
  57.         headers['Content-Length'] = len(params)     51Testing软件测试网'uj sn y
  58.             51Testing软件测试网"G!pw3ylw?3g1s Y
  59.         try:     51Testing软件测试网+K^8G9U+LlX
  60.             if method == POST:     
    SO~+_%P0
  61.                 conn.request(method, url, params, headers)     51Testing软件测试网cV m%S gX
  62.             else:     
    n0Gg.g0PS3u0
  63.                 conn.request(method, url + params)     
    yn'L ]'{gRA qe0
  64.             response = conn.getresponse()     
    C0pXCm(v[0
  65.         except Exception, e:     
    x5W%e._oU fC%H8{r.d0
  66.             log('request failed. method = %s, url = %s, params = %s headers = %s'%(     
    g4D6\ k5Qf8m p0
  67.                         method, url, params, headers))     51Testing软件测试网8qU@Cfh\
  68.             log(str(e))     
    rxN3G'N-Y"a?0
  69.             fail_op(task, UNEXPECTED_ERROR, log)     
    ^ Sgjo0| n*s"Sr0
  70.             continue     
    SW&mf+`/k$te,Kt0
  71.                  
    ZMtvj4A7P0
  72.         if response.status != httplib.OK:     
    0BQ)T)sknL8C|K0
  73.             fail_op(task, response.status, log)     
    ~x4w Gw4C0
  74.             continue     51Testing软件测试网ung F)_6Nm.g i+h2C0J
  75.                  51Testing软件测试网R+qQ(Q8\8{!C
  76.         data = response.read()     
    N/B7p U"Ma0
  77.         results.put((tid, data), True)     51Testing软件测试网|a}A ChO+T
  78.             51Testing软件测试网I~7T[z4`0?_
  79. class HttpPool(object):     
    jA,x!b#V9u0
  80.     def __init__(self, threads_count, fail_op, log):     51Testing软件测试网PF2ZbnA0W#v-P7F
  81.         self._tasks = Queue()     51Testing软件测试网U5o@u/B5sDe {{
  82.         self._results = Queue()     
    p Seoj2r0
  83.             
    'L ~;n1I;?T.C:z[m I0
  84.         for i in xrange(threads_count):     
    8CJ^y#CP(K)WA0
  85.             thread.start_new_thread(get_remote_data,(self._tasks, self._results, fail_op, log))     51Testing软件测试网]wUW[H9a$eW
  86.                  
    4x~6sZs:e0
  87.     def add_task(self, tid, host, url, params, headers = {}, method = 'GET', timeout = None):     51Testing软件测试网Fd&e0tP3a
  88.         task = {     51Testing软件测试网.r y}z$t&f\}~ k
  89.             'id' : tid,     51Testing软件测试网 a?jGf0th+_
  90.             'conn_args' : {'host' : host} if timeout is None else {'host' : host, 'timeout' : timeout},     
    Yy8crH%X s0
  91.             'headers' : headers,     51Testing软件测试网RNSE%y^ u{4`
  92.             'url' : url,     51Testing软件测试网#^9t1|mS
  93.             'params' : params,     
    s*f)|s)^]3j&{0
  94.             'method' : method,     
    R#wXH(Fb9GB?N0
  95.             }     51Testing软件测试网db]/pnnG$T
  96.         try:     
    rrwF3If0
  97.             self._tasks.put_nowait(task)     51Testing软件测试网 K]Kd ^L;T*^`
  98.         except Full:     51Testing软件测试网C%G3^;CQ(Ob}h:H.X
  99.             returnFalse     51Testing软件测试网2m(H9o S"C7s+v
  100.         return True     51Testing软件测试网4b"D4JP$w6NBH,[
  101.             
    C b$M~8yL5\5x{0
  102.     def get_results(self):     
    .O'k~|6jn7x2AvZ$a0
  103.         results = []     51Testing软件测试网-L E [i$i
  104.         while True:     
    %e6J5ni$S B yx0
  105.             try:     51Testing软件测试网k#j}o0qp
  106.                 res = self._results.get_nowait()     51Testing软件测试网a1E_UHh0de
  107.             except Empty:     
    ` h.p:rX%X0
  108.                 break     51Testing软件测试网Lg;l v$]+}'y
  109.             results.append(res)     
    &I7yf%EU \0
  110.         return results     51Testing软件测试网4P!h].n G Y
  111.             
    *bw9m2V:M$tJ)Af0
  112. deftest_google(task_count, threads_count):     51Testing软件测试网n2U9|0Z Fz9m/a
  113.     hp = HttpPool(threads_count, base_fail_op, base_log)     51Testing软件测试网/P&z7Oj2|;a
  114.     for i in xrange(task_count):     51Testing软件测试网2Es h;m3D9a
  115.         if hp.add_task(i,     51Testing软件测试网!_p/k2B9x2G
  116.                 'www.google.cn',     51Testing软件测试网$@l${I1P'KK*Qh?
  117.                 '/search?',     
    $I'\P(Z$Gj0
  118.                 {'q' : 'lai'},     51Testing软件测试网R V1|+R2b a5dHPT^5l
  119. #               method = 'POST'     51Testing软件测试网*Yn-|~c
  120.                 ):     51Testing软件测试网 JC5p"zX0] Kh\ZO
  121.             print 'add task successed.'     
    NQ;~vY0
  122.                  51Testing软件测试网*c-x biFwh
  123.     while True:     
    SfV7i!x0
  124.         results = hp.get_results()     
    Ro6k9h} ?%G0
  125.         if not results:     
    #l9_+]3z N0
  126.             time.sleep(1.0 * random.random())     51Testing软件测试网/C*Y&~@K2T
  127.         for i in results:     
    ;K5meHVd0
  128.             print i[0], len(i[1])     51Testing软件测试网,g,T SX9~q}
  129. #           print unicode(i[1], 'gb18030')     
    Nj({/qQe-]:kv$h Hh0
  130.                  
    H1H;DKa Sz0
  131. if __name__ == '__main__':     51Testing软件测试网7d q"h7Scp(Ro$?
  132.     import sys, random     
    }(V(['rj0B7y0
  133.     task_count, threads_count = int(sys.argv[1]), int(sys.argv[2])     51Testing软件测试网:b+Lb8Kq6\ X4Gq
  134.     test_google(task_count, threads_count)   
有兴趣想尝试运行的朋友,可以把它保存为 xxxx.py,然后执行 python xxxx.py 10 4,其中 10 表示向 google.cn 请求 10 次查询,4 表示由 4 条线程来执行这些任务。51Testing软件测试网 G-I.L3nm"Vo5XGK7E

`7D5l_ b?r"B0
!P!wn9B;SynZc0转自http://blog.csdn.net/lanphaday/archive/2009/04/16/4083852.aspx

TAG: Python python

 

评分:0

我来说两句

Open Toolbar