博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【爬虫小程序:爬取斗鱼所有房间信息】Xpath(线程池版)
阅读量:5023 次
发布时间:2019-06-12

本文共 3127 字,大约阅读时间需要 10 分钟。

 
# 本程序亲测有效,用于理解爬虫相关的基础知识,不足之处希望大家批评指正
from queue import Queueimport requestsfrom lxml import etreefrom multiprocessing.dummy import Poolimport time"""爬取目标:http://www.qiushibaike.com/8hr/page/1    利用线程池实现"""class QiuShi:    def __init__(self):        # url和headers        self.base_url = 'http://www.qiushibaike.com/8hr/page/{}'        self.headers = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36'        # 定义队列,用来传递数据        self.url_queue = Queue()        self.request_queue = Queue()        self.html_queue = Queue()        # 初始化线程池        self.pool = Pool()        # 定义计数器        self.request_num = 0        self.response_num = 0        self.is_running = True    def get_url_list(self):        """获取所有的url"""        for i in range(1, 14):            target_url = self.base_url.format(i)            print(target_url)            self.request_num += 1            self.url_queue.put(target_url)    def request_url(self):        """向url发起请求"""        target_url = self.url_queue.get()        response = requests.get(target_url, self.headers)        self.request_queue.put(response)        self.url_queue.task_done()    def get_content(self):        """获取数据"""        html_text = self.request_queue.get().content.decode()        html = etree.HTML(html_text)        div_list = html.xpath('//div[@id="content-left"]/div')        content_list = []        for div in div_list:            item = {}            item['author'] = div.xpath('.//h2/text()')[0].strip()            item['content'] = div.xpath('.//span/text()')[0].strip()            print(item)            content_list.append(item)        self.html_queue.put(content_list)        self.request_queue.task_done()    def save_data(self):        """保存入库"""        data_list = self.html_queue.get()        for data in data_list:            with open('qiushi.text', 'a+') as f:                f.write(str(data))                f.write('\r\n')        self.html_queue.task_done()    def execute_request_response_save(self):        """线程池子,执行请求,回应,保存"""        self.request_url()        self.get_content()        self.save_data()        self.response_num += 1    def _callback(self,temp):        """线程池的回调函数:"""        if self.is_running:            self.pool.apply_async(self.execute_request_response_save, callback=self._callback)    def main(self):        """主程序逻辑"""        self.get_url_list()        # 执行线程池        for n in range(4):  # 用4个线程去执行线程池任务            self.pool.apply_async(self.execute_request_response_save,callback=self._callback)        # time.sleep(10)        while True:            if self.request_num == self.response_num:                self.is_running = False                break        #思考: 为什么要加上这个while?        """        如果不写这个while循环,那么,线程池的异步任务在没有进入回调函数的时候,主线程就结束了        那问题又来了,python3中主线程不是不影响用户子线程的吗?        注意了:我们这里用的是单进程单线程任务,只不过用的是线程池的方法来解决问题        当主进程结束了,那么进程内部的线程也会一起结束                这个while循环就是让主线程在这里等待线程池中的子线程,等子线程所有的任务都完成了,再一起结束        他的作用类似于join()函数        """if __name__ == '__main__':    qiushi = QiuShi()    qiushi.main()

 

转载于:https://www.cnblogs.com/888888CN/p/10070257.html

你可能感兴趣的文章
keepalived介绍
查看>>
css3 标签 background-size
查看>>
python itertools
查看>>
Linux内核调试技术——jprobe使用与实现
查看>>
样式、格式布局
查看>>
ubuntu设计文件权限
查看>>
Vue双向绑定原理详解
查看>>
Android基础总结(5)——数据存储,持久化技术
查看>>
关于DataSet事务处理以及SqlDataAdapter四种用法
查看>>
bootstrap
查看>>
http://lorempixel.com/ 可以快速产生假图
查看>>
工程经验总结之吹水"管理大境界"
查看>>
为什么JS动态生成的input标签在后台有时候没法获取到
查看>>
20189210 移动开发平台第六周作业
查看>>
java之hibernate之基于外键的双向一对一关联映射
查看>>
rxjs一句话描述一个操作符(1)
查看>>
第一次独立上手多线程高并发的项目的心路历程
查看>>
ServiceStack 介绍
查看>>
Centos7下载和安装教程
查看>>
无谓的通宵加班之后的思索
查看>>