zoukankan      html  css  js  c++  java
  • Python 多线程爬虫

    1. 并发,并行的理解

    # 并发:同一时间段同时运行
    # 并行:同一时刻同时运行
    # 时间片轮转法:10个视屏不间断播放,是并发运行,但给人的错觉是并行
    # 高IO密集(比如在一个刚运行的代码前就有设置的)  阻塞,cup算法密集
    

    2. 用代码实现多线程爬虫

    ***用多线程爬虫,最重要的就是传参,获取数据,思路********
    import threading,requests
    # 导入多线程锁机制
    from threading import Lock
    # 导入线程队列
    from queue import Queue
    from lxml import etree
    import pymongo
    # 爬虫类,负责采集数据的
    class CrawThread(threading.Thread):
        # 初始化init方法,接收参数
        def __init__(self,name,pageQueue,dataQueue):
            super().__init__()
            self.name = name
            self.pageQueue = pageQueue
            self.headers = {
                'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36'
            }
            self.dataQueue = dataQueue
    
        # 执行run方法,在def函数调用时执行
        def run(self):
            # 爬取的页数不确定,格式化输出
            base_url = 'https://www.xiaohua.com/duanzi?page=%s'
            while 1:
                try:
                    print('开始url')
                    # 传参时要抓取几页的数据已准备好直接get获取,block为False用try捕获异常抓取结束,就终止循环
                    page = self.pageQueue.get(block=False)
                    # 将页码拼接
                    url = base_url % page
                    res = requests.get(url=url,headers=self.headers)
                    self.dataQueue.put(res.text)
                    print('URL完成')
                except:
                    break
    
    # 数据解析类
    class Parse(threading.Thread):
        def __init__(self,name,dataQueue,look):
            super().__init__()
            self.name = name
            self.dataQueue = dataQueue
            self.look = look
    
        def run(self):
            while 1:
                try:
                    html = self.dataQueue.get(block=False)
                    print('正在解析')
                    # 把获取的HTML的文本放在下一个函数的里进行操作
                    self.parserver(html)
                    print('解析完毕')
                except:
                    break
                    
        def parserver(self,html):
            # 解析
            tree = etree.HTML(html)
            div_list = tree.xpath('//div[@class="one-cont"]')
            for div in div_list:
                item = {}
                author = div.xpath('./div/div/a/i/text()')
                item['author'] = author[0]
                # 上锁
                with self.look:
                    self.save(item)
    
        def save(self,item):
            # 连接MongoDB数据库
            conn = pymongo.MongoClient('localhost',27017)
            db = conn.XIAOHUA
            table = db.xh
            table.insert_one(item)
    
    def main():
        # 存放URl----实例化队列对象
        pageQueue = Queue()
        for j in range(1,11):
            # put将所需要的数据存入
            pageQueue.put(j)
        #存放脏数据
        dataQueue = Queue()
        crawlist = ['爬虫1号','爬虫2号','爬虫3号']
        # join等待进程以防有一个进程死掉
        for i in crawlist:
            c = CrawThread(i,pageQueue,dataQueue)
            c.start()
            c.join()
        # 实例化机制锁对象
        look = Lock()
        jiexi = ['解析1号','解析2号','解析3号',]
        for var2 in jiexi:
            cc = Parse(var2,dataQueue,look)
            cc.start()
            # 等待其他线程执行,以防提早结束其他线程死掉
            cc.join()
    
    
    if __name__ == '__main__':
        main()
    
    
  • 相关阅读:
    pytest 框架生成 pytest
    pytest 之数据驱动参数化:pytest.mark.parametrize
    web 网站表单测试、搜索查询测试、删除测试、数据库测试知识点
    pytest 之 fixture 的前置后置功能
    pytest 框架之pytest-html报告生成
    Initialization of bean failed; nested exception is java.lang.
    使用jmeter测试Oracle&&MySQL数据库性能
    jmeter的日常特殊参数化
    压测出现各种奇葩问题,求围观
    weblogic性能调优
  • 原文地址:https://www.cnblogs.com/xinzaiyuan/p/12382253.html
Copyright © 2011-2022 走看看