python爬虫爬学校民主湖论坛(3)----------多线程搜索帖子

</pre>     本文提到的功能已经在上一篇文章中实现 过。这次则是尝试用线程池来加速访问,一则是练习一下线程池使用的方法,而是为下一步实现回复内容的爬取做准备。首先,感谢Adam_Kevint对我的关注,本来只是想写个爬虫练习一下自己的Python编程的,没想到还有人关注。先透露一下,帖子回复的搜索已经大致实现了,不过还没实现线程池功能搜索速度很慢,另外民主湖模拟登陆也实现了,整理整理,有时间就上传上去。</p><p></p><p>      首先,本次实现线程池,有个小问题,就是线程建立时间很久,建立完成之后,很快就搜索完毕,中间有很长一段空白期,用户体验感肯定不好,我继续努力,也希望大神提提宝贵意见。第二,本程序中为了对文件进行有效的读写,采用了互斥锁,感觉挺好用的。第三,就是熟悉了Python任意参数的传递,网上有很多Python的线程池例子,但是参数是固定的,如http://blog.csdn.net/pi9nc/article/details/17056961,不好匹配,我试了几个,觉得现在用这个不错http://developer.51cto.com/art/201002/185290.htm。在此感谢给我大神(我只是代码的搬运工)</p><p>    本文是针对第二篇文章修改的,将一个主题用一个线程来搜索,采用了十个线程,按照队列模型进行搜索。所以只是改动了findAuthorArticleWithoutLogin(authorId,date1)这个函数,还有就是findAuthorArticle(authorId,Fid,FidName,date1)中加了个互斥锁<pre class="python" name="code">           if mutex.acquire(1): 

                     #保存到文件
                     f.writelines(str(FidName)+u',第'+str(i)+u'页,'+item[1]+','+info+'\n\r')
                     mutex.release()
实现了文件的独立访问。两个类,一个是工作类,另外一个 是线程管理类。就这样吧,上代码!

# -*- coding: utf-8 -*-
"""
Created on Fri Mar 06 18:13:48 2015
可以爬到所有无需登录的模块
本模块可以从第一页访问,然后根据用户注册时间与网页贴子时间相比较,适时结束访问,加快搜索速度。!
输入参数:
        用户ID
        用户注册时间:需要登录查看
@author: KyleHuang
@Address: Chongqing University
"""
import re  
import urllib2
import datetime
import time
import Queue, threading, sys   
from threading import Thread   
import time,urllib   
# working thread   
class Worker(Thread):   
   worker_count = 0   
   def __init__( self, workQueue, resultQueue, timeout = 0, **kwds):   
       Thread.__init__( self, **kwds )   
       self.id = Worker.worker_count   
       Worker.worker_count += 1   
       self.setDaemon( True )   
       self.workQueue = workQueue   
       self.resultQueue = resultQueue   
       self.timeout = timeout   
       self.start( )   
   def run( self ):   
       ''' the get-some-work, do-some-work main loop of worker threads '''   
       while True:   
           try:   
               callable, args, kwds = self.workQueue.get(timeout=self.timeout)   
               res = callable(*args, **kwds)   
               #print "worker[%2d]: %s" % (self.id, str(res) )   
               self.resultQueue.put( res )   
           except Queue.Empty:   
               break   
           except :   
               print 'worker[%2d]' % self.id, sys.exc_info()[:2]   
                  
class WorkerManager:   
   def __init__( self, num_of_workers=10, timeout = 1):   
       self.workQueue = Queue.Queue()   
       self.resultQueue = Queue.Queue()   
       self.workers = []   
       self.timeout = timeout   
       self._recruitThreads( num_of_workers )   
   def _recruitThreads( self, num_of_workers ):   
       for i in range( num_of_workers ):   
           worker = Worker( self.workQueue, self.resultQueue, self.timeout )   
           self.workers.append(worker)   
           print 'add a task'
   def wait_for_complete( self):   
       # ...then, wait for each of them to terminate:   
       while len(self.workers):   
           worker = self.workers.pop()   
           worker.join( )   
           if worker.isAlive() and not self.workQueue.empty():   
               self.workers.append( worker )   
       #print "All jobs are are completed."   
   def add_job( self, callable, *args, **kwds ):   
       self.workQueue.put( (callable, args, kwds) ) 
       print 'Add a task!'
   def get_result( self, *args, **kwds ):   
       return self.resultQueue.get( *args, **kwds )  
   

def findAuthorArticleWithoutLogin(authorId,date1):

    FidList={280:u'计算机技术',119:u'学术民主湖',14:u'江风竹雨',27:u'人文社科',63:u'好摄之徒',17:u'书香重大',
              109:u'外语角',83:u'黄桷树下',123:u'鱼食天下',107:u'鱼游天下',30:u'激情天下',181:u'数码广场',
             18:u'轻松一刻',92:u'老乡会所',195:u'健康大家谈',100:u'心语新缘',234:u'曝光台',103:u'张贴栏',
             138:u'生物学院'
             #203:u'租房',218:u'兼职',180:u'民主湖超市'
             }
    #findAuthorArticle(authorId,100,FidList[100],date1)
   
    wm = WorkerManager(10)   
    for fid in FidList:   #将搜索加入到线程池中
       wm.add_job( findAuthorArticle, authorId,fid,FidList[fid],date1 )   
    wm.wait_for_complete()   #等待工作完成

       #findAuthorArticle(authorId,key,FidList[key],date1)
def findAuthorArticle(authorId,Fid,FidName,date1):
    ###该函数主要用来访问近几年用户,从第一页访问
     pageStart=1#从第一页访问
     pageEnd=500#最多访问500页,结束
     urlstr='http://www.cqumzh.cn/bbs/forumdisplay.php?fid='+str(Fid);
     matchstr='space.php?uid='+str(authorId)
     for i in range(pageStart,pageEnd):
         print FidName+u'爬虫爬到第'+str(i)+u'页'
         #合成URL路径
         urlstr2=urlstr+'&page='+str(i)
         #模拟请求网址
         request = urllib2.Request(urlstr2)
         request.add_header('User-Agent', 'fake-client')
         response = urllib2.urlopen(request)
         myPage =response.read()
         #匹配目标内容
         myItems=re.findall('<a title=(.*?)>(.*?)</a></span>.*?<td align="center" style="overflow:hidden"nowrap="nowrap">\r\n<cite>\r\n<a href="(.*?)">(.*?)</a>',myPage,re.S)
         for item in myItems:    
          #print item[1]+'authour='+item[2]
          #f.writelines(item[1]+'authour='+item[2]+'\n\r')
             str1=str(item[2])
             #找到目标作者
             if str1 == matchstr :
                 #addr=getWebAdress(item[0])
                 info=item[0].replace('&','&')
                 print FidName+u','+item[1]+','+info
                 if mutex.acquire(1): 

                     #保存到文件
                     f.writelines(str(FidName)+u',第'+str(i)+u'页,'+item[1]+','+info+'\n\r')
                     mutex.release()
         length=len(myItems)
         date2=getItemPage(myItems[length-1][0])
         #print date2
         dderror=date2-date1
         if dderror.days<0:
             return
          

def getWebAdress(objStr):
             addr=re.findall('.*?href="(.*?)"',objStr,re.S)
             return addr[0]
def getItemPage(objStr):
    mItems=re.findall('\d{4}-\d{1,2}-\d{1,2}',objStr,re.S)
    mdate=datetime.datetime.strptime(str(mItems[0]), "%Y-%m-%d")
    return mdate
if __name__=="__main__":
    #此处输入搜索需要的信息
    authorId=raw_input(u'请输入作者ID:');
    registerDate =raw_input(u'请输入开始日期,(作者注册时间),格式:xxxx-xx-xx');
    dd=datetime.datetime.strptime(registerDate, "%Y-%m-%d")
    print u"爬虫开始爬民主湖了 ......"
    f = open('Bid'+str(authorId)+'.txt','w+')  
    f.writelines(u"作者"+str(authorId)+u"\n\r") 
    mutex=threading.Lock()
    findAuthorArticleWithoutLogin(authorId,dd)
    f.close()


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值