python分布式爬虫

来源:互联网 发布:淘宝怎么追评不了 编辑:程序博客网 时间:2024/06/06 21:45

这篇文章是我借鉴了网上一篇利用Python队列实现多进程任务程序的文章,加上自己的想法写了一个简单的多进程并发爬虫,以主从关系,一个master和多个slave,master负责派发爬取任务,slave负责去执行任务,并返回结果。由于我也是菜鸟一个,水平有限,也是依葫芦画瓢,所以有什么不对的,大神勿喷!下面的代码可以直接跑的:先运行

Master类派发任务,再运行Slave类,Slave类可以拷贝多个放在不同的机器上运行

我这里爬取的是腾讯社会新闻的例子:

环境

python2.7

需安装 multiprocessing

# -*- coding: utf-8 -*-import reimport requests#url类,用于获取要爬取的新闻标题链接地址class TencentNewUrl:    #获取标题链接列表    def getTiele_Url_List(self):        params={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3000.4 Safari/537.36"}        response=requests.get("http://society.qq.com/",params=params)        html=response.text        pattern="<a target=\"_blank\" class=\"linkto\" href=\".*?\">.*?</a>"        news_url_list=re.findall(pattern,html)        return news_url_list
# -*- coding: utf-8 -*-import reimport requests#腾讯社会新闻爬虫类,title_a:新闻标题a标签,num 编号class TencentNewsSpider:    def __init__(self,title_a,num):        self.title_a=title_a        self.num=num    #获取数据    def getItem(self):        #访问参数        params={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3000.4 Safari/537.36"}        url=re.findall("http://.*?\"",self.title_a)[0]        url=url.replace("\"","")        mydata={}        response=requests.get(url,params=params)        html=response.text        p_title=">.*?</a>" #标题        p_source="<span class=\"color-a-1\" bosszone=\"jgname\"><a target=\"_blank\" href=\".*?\">.*?</a></span>" #来源        p_time="<span class=\"article-time\">.*?</span>" #发布时间        p_cmt_num="<a href=\".*?\" id=\"cmtNum\" bosszone=\"Ncomm\" target=\"_blank\">.*?</a>" #点赞数        mydata["title"]=re.findall(p_title,self.title_a)[0].replace(">","").replace("</a","")        mydata["source"]=re.findall(p_source,html)        mydata["time"]=re.findall(p_time,html)        mydata["cmt_num"]=re.findall(p_cmt_num,html)        return mydata
# -*- coding: utf-8 -*-from multiprocessing.managers import BaseManagerfrom tencent_news_url_list import TencentNewUrlfrom tencent_news_spider import TencentNewsSpiderfrom multiprocessing import Queueimport time#主机管理类,用于任务派发class Master:    def __init__(self):        # 派发出去的任务队列        self.dispatched_task_queue = Queue()        # 完成的任务队列        self.finished_task_queue = Queue()    def get_dispatched_task_queue(self):        return self.dispatched_task_queue    def get_finished_task_queue(self):        return self.finished_task_queue    #开始任务    def start(self):        # 把派发作业队列和完成作业队列注册到网络上        BaseManager.register('get_dispatched_task_queue', callable=self.get_dispatched_task_queue)        BaseManager.register('get_finished_task_queue', callable=self.get_finished_task_queue)        # 监听端口和启动服务,authkey为验证码,自己随便取的,address改成自己的ip        manager = BaseManager(address=('192.168.1.107', 8888), authkey='tencent')        manager.start()        # 使用上面注册的方法获取队列        dispatched_tasks = manager.get_dispatched_task_queue() #获取派发队列        finished_tasks = manager.get_finished_task_queue() #获取返回队列        while True:            item_list=[] #任务完成返回结果列表            url_list=TencentNewUrl().getTiele_Url_List()            for index,title_a in enumerate(url_list):                tencent_spider=TencentNewsSpider(title_a,index)                dispatched_tasks.put(tencent_spider)                print "派发任务: "+str(index)            while not dispatched_tasks.empty():                tencent_spider2 = finished_tasks.get()                item_list.append(tencent_spider2.getItem())                print "将任务 "+str(tencent_spider2.num)+" 返回结果添加到列表中"            print "本次任务完成结果:"            print len(item_list)            print item_list            #暂停10秒后继续进行下一轮的任务派发            time.sleep(10)        manager.shutdown()if __name__ == "__main__":    master = Master()    master.start()

# -*- coding: utf-8 -*-import timefrom Queue import Queuefrom multiprocessing.managers import BaseManager#从机类class Slave:    def __init__(self):        # 派发出去的任务队列        self.dispatched_task_queue = Queue()        # 完成的任务队列        self.finished_task_queue = Queue()    def start(self):        # 把派发任务队列和完成任务队列注册到网络上        BaseManager.register('get_dispatched_task_queue')        BaseManager.register('get_finished_task_queue')        # 连接master        server = '192.168.1.107'        print('连接主机服务器 %s...' % server)        manager = BaseManager(address=(server,8888), authkey='tencent')        manager.connect()        # 使用上面注册的方法获取队列        dispatched_tasks = manager.get_dispatched_task_queue()        finished_tasks = manager.get_finished_task_queue()        # 运行作业并返回结果,这里只是模拟作业运行,所以返回的是接收到的作业        while True:            try:                tencent_spider = dispatched_tasks.get(timeout=1)                print "正在执行任务..."+str(tencent_spider.num)                tencent_spider.getItem()                time.sleep(1)                finished_tasks.put(tencent_spider)            except Exception:                continueif __name__ == "__main__":    slave = Slave()    slave.start()


0 0
原创粉丝点击