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

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

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

文章来源
  • 文章来源:【转载】
  1. #!/usr/bin/envpython   
    2n nvi$v2G R*~0
  2. # -*- coding:utf-8 -*-     
    ^s{pm ]h}!f(a0
  3. import urllib, httplib     
    O|DO HE!A0
  4. import thread     51Testing软件测试网fr!B {ZD
  5. import time     51Testing软件测试网1^$r b}1Ge
  6. from Queue import Queue, Empty, Full     51Testing软件测试网 q!K!uV6?i8L
  7. HEADERS = {"Content-type": "application/x-www-form-urlencoded",     51Testing软件测试网%P zC3|;rq
  8.                         'Accept-Language':'zh-cn',     
    ] t \1Gy!i#g0
  9.                         'User-Agent': 'Mozilla/4.0 (compatible; MSIE 6.0;Windows NT 5.0)',     51Testing软件测试网v @8RXbEk&a
  10.                         "Accept": "text/plain"}     51Testing软件测试网;N\4x Sy'O-nb`1H
  11. UNEXPECTED_ERROR = -1     51Testing软件测试网,]7]S%Blv
  12. POST = 'POST'     
    x]\5yR \G0
  13. GET = 'GET'     
    4D6U i*ImAy SQ"Z0
  14. def base_log(msg):     
    {FCgal _0
  15.     print msg     51Testing软件测试网:{H X(y(u6_yr
  16. def base_fail_op(task, status, log):     
    ,H,_i"\2N,y0| N0
  17.     log('fail op. task = %s, status = %d'%(str(task), status))     
    "Z!A T,[@E Yc0
  18. def get_remote_data(tasks, results, fail_op = base_fail_op, log = base_log):     51Testing软件测试网RX;yJe j C
  19.     while True:     
    5u"H g_U+s0
  20.         task = tasks.get()     
    aO:W:lZ%^0
  21.         try:     51Testing软件测试网9f#]8p&{Z7B.b`
  22.             tid = task['id']     51Testing软件测试网DD/tMA4^h
  23.             hpt = task['conn_args'] # hpt <= host:port, timeout     51Testing软件测试网s1Jgl)M L {
  24.         except KeyError, e:     51Testing软件测试网5hn k v bo
  25.             log(str(e))     51Testing软件测试网-T)d Gm3T
  26.             continue     
    ,v liv)B/lX$Y%R3r0
  27.         log('thread_%s doing task %d'%(thread.get_ident(), tid))     51Testing软件测试网7@6?8e3e7_j#u"p
  28.         #log('hpt = ' + str(hpt))     51Testing软件测试网~_k h,Z1nb6b
  29.         conn = httplib.HTTPConnection(**hpt)     51Testing软件测试网r_ }-z]'o*nf+F
  30.                  
    1X0jp9[5|Ew)X0
  31.         try:     
    &T G.Q1?4p,C0
  32.             params = task['params']     
    |1LQ'C:Q6z4[A3o0
  33.         except KeyError, e:     51Testing软件测试网6adGn*^5t.znK
  34.             params = {}     
    x*g5H ~7n!I0
  35.         params = urllib.urlencode(params)     51Testing软件测试网,mZo w$m m)hBHP
  36.         #log('params = ' + params)     
    $J%I3?3{0[bo0
  37.             
    oIi4U Y:k%\3O:q5m0
  38.         try:     
    ${-hw$nf.{+u0
  39.             method = task['method']     51Testing软件测试网W*Hq,b4~ _
  40.         except KeyError:     
    J mj#V [M D;aJ0
  41.             method = 'GET'     
    }@@6Sz9rd0
  42.         #log('method = ' + method)     51Testing软件测试网$rKb,gj;e
  43.             
    z.NW1Jj}J0
  44.         try:     
    r|:j8t"~]f!XyvA0
  45.             url = task['url']     51Testing软件测试网f|!R.p5Y7w2kr
  46.         except KeyError:     
    IwNZJ|0
  47.             url = '/'     
    +eUd%w(Ox0
  48.         #log('url = ' + url)     51Testing软件测试网,x])e{*j-XW
  49.             
    c6j DK5VV(M F)}0
  50.         headers = HEADERS     
    Qx,YJ)d6x XUc0
  51.         try:     
    c&~S/r7Hm|0
  52.             tmp = task['headers']     51Testing软件测试网6f];jah0dz%M~(E1\m
  53.         except KeyError, e:     
    [Y!P8f `rH5o z0
  54.             tmp = {}     51Testing软件测试网o+n C4Ma.? ~[#y
  55.         headers.update(tmp)     
    %gG`r v{ n0
  56.         #log('headers = ' + str(headers))     
    )`.B_F Hz9g,^"~0
  57.         headers['Content-Length'] = len(params)     
    k)TEw;TK`0
  58.             51Testing软件测试网0lo-sI"w
  59.         try:     51Testing软件测试网gj)}&`u
  60.             if method == POST:     51Testing软件测试网.bGRf$j8av9Qm |
  61.                 conn.request(method, url, params, headers)     
    #mvD"cd[0
  62.             else:     
    jM8m7v{,Z'JsmM*r0
  63.                 conn.request(method, url + params)     51Testing软件测试网? M:{@:x(uH)SQ
  64.             response = conn.getresponse()     
    .g V9EE6A0
  65.         except Exception, e:     51Testing软件测试网2M:E,NtWNsW%y
  66.             log('request failed. method = %s, url = %s, params = %s headers = %s'%(     51Testing软件测试网)y4^I0}.Z^,ZR Ape
  67.                         method, url, params, headers))     51Testing软件测试网!@ YA4Q&dhp
  68.             log(str(e))     51Testing软件测试网k3Z.e0th
  69.             fail_op(task, UNEXPECTED_ERROR, log)     
    L@J*z3qG"O0
  70.             continue     
    ,I!]#W k e o3U0
  71.                  
    4w#L}#JI0rN Go7oO0
  72.         if response.status != httplib.OK:     
    S[^4V8o%v vc!W|0
  73.             fail_op(task, response.status, log)     
    0g$np9uL0
  74.             continue     
    a'F5o,W y3JUW{B0
  75.                  51Testing软件测试网U9_G4G+EqOn
  76.         data = response.read()     51Testing软件测试网Q mk,j1{t f
  77.         results.put((tid, data), True)     51Testing软件测试网&} Y*F]hD*k
  78.             51Testing软件测试网H-g5D d'f t;ZL
  79. class HttpPool(object):     
    !I _7S)[.u1Ha#~!Q0
  80.     def __init__(self, threads_count, fail_op, log):     51Testing软件测试网*OULk cR HH`^ Q
  81.         self._tasks = Queue()     
    P9]*LQ-f0
  82.         self._results = Queue()     
    &K)y8x%AQOR#Q0
  83.             
    .k$Wh9CIp8K0P0s+lw0
  84.         for i in xrange(threads_count):     51Testing软件测试网QAs-{7p$h.T-q
  85.             thread.start_new_thread(get_remote_data,(self._tasks, self._results, fail_op, log))     
    j+dr6egO0
  86.                  
    %_*S r E:f7T8E@0
  87.     def add_task(self, tid, host, url, params, headers = {}, method = 'GET', timeout = None):     
    [)]cp}0
  88.         task = {     
    ^Z2a+^N4m;a2\t7g0
  89.             'id' : tid,     
    G)|$rR4t@s,e0
  90.             'conn_args' : {'host' : host} if timeout is None else {'host' : host, 'timeout' : timeout},     51Testing软件测试网"Hh3v'?W Ov\+iMb
  91.             'headers' : headers,     
    /@%Q$E`uI0
  92.             'url' : url,     
    c"}{7Yu#q-c0
  93.             'params' : params,     51Testing软件测试网 I;~)X3iH-ejC z7`
  94.             'method' : method,     51Testing软件测试网["n.p ibz
  95.             }     51Testing软件测试网'DD }']~\k+{
  96.         try:     51Testing软件测试网"v0{j+J5o&r i b@
  97.             self._tasks.put_nowait(task)     51Testing软件测试网9W9r Uk&EZ.z
  98.         except Full:     
    In(Z(yI*|5o0
  99.             returnFalse     51Testing软件测试网/sR:`X:`0ju
  100.         return True     
    %@l(`0o`C0W0
  101.             
    'n9D s#v _0
  102.     def get_results(self):     51Testing软件测试网^E(k4T]B2s s'{
  103.         results = []     51Testing软件测试网1A?"kZsm1re
  104.         while True:     
    u"?trQ0
  105.             try:     51Testing软件测试网1?9ptb!l#L4U
  106.                 res = self._results.get_nowait()     51Testing软件测试网t[`0[#a$t r^
  107.             except Empty:     
    0|/YVCw2Kt(GP*P{W}0
  108.                 break     
    -KGp)gm/\0
  109.             results.append(res)     
    -S+FD TP$BH0
  110.         return results     51Testing软件测试网-\ gX+qb*m
  111.             51Testing软件测试网fyx-k G6ML7E}3Qe.hw
  112. deftest_google(task_count, threads_count):     
    9GW*B nXQLf-EMX0
  113.     hp = HttpPool(threads_count, base_fail_op, base_log)     
    cNJ sY!a I0
  114.     for i in xrange(task_count):     
    8FP\3r.Gv}X3JzN0
  115.         if hp.add_task(i,     
    [e3[,s,Q:{@"P0
  116.                 'www.google.cn',     
    {C(V"T$X)NX0
  117.                 '/search?',     51Testing软件测试网uAS$q2N7c(I
  118.                 {'q' : 'lai'},     51Testing软件测试网(W"lI1s$E
  119. #               method = 'POST'     
    JZ7^d+A8Ux0
  120.                 ):     
    V5}z\a0
  121.             print 'add task successed.'     
    )m&Hu1m)_m p$X'{S f'Z0
  122.                  51Testing软件测试网'U\mT:w;a
  123.     while True:     51Testing软件测试网d#z&Mc$L`I
  124.         results = hp.get_results()     
    !\n8X/h8p0}?M0
  125.         if not results:     51Testing软件测试网)v+Ed.U(q {0qNM
  126.             time.sleep(1.0 * random.random())     51Testing软件测试网(@+q-UpC5LiFi
  127.         for i in results:     
    4\{.e:H P$c1ZM0
  128.             print i[0], len(i[1])     51Testing软件测试网TOF6MD'V"`"t[
  129. #           print unicode(i[1], 'gb18030')     51Testing软件测试网u;{$g4{l|#|Y
  130.                  
    7I ~5K3`+{w7i,K0
  131. if __name__ == '__main__':     
    `-N P2i [-[n0
  132.     import sys, random     51Testing软件测试网6im&UU)z"uX4u
  133.     task_count, threads_count = int(sys.argv[1]), int(sys.argv[2])     
    4q$z$E!tm^9uW4@0
  134.     test_google(task_count, threads_count)   
有兴趣想尝试运行的朋友,可以把它保存为 xxxx.py,然后执行 python xxxx.py 10 4,其中 10 表示向 google.cn 请求 10 次查询,4 表示由 4 条线程来执行这些任务。
7O-W"J'Dc7LV051Testing软件测试网[@$b A\n3}
51Testing软件测试网-A[Zgb;_
转自http://blog.csdn.net/lanphaday/archive/2009/04/16/4083852.aspx

TAG: Python python

 

评分:0

我来说两句

Open Toolbar