xinzaiyuan

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()

分类:

技术点:

相关文章: