尝试用 aiohttp 写爬虫,但这么写不知道该怎么停止循环?

尝试用 aiohttp 写爬虫,但这么写不知道该怎么停止循环?,第1张

尝试用 aiohttp 写爬虫,但这么写不知道该怎么停止循环?,第2张

使用 aiohttp 试着写了一个爬虫,但是发现可能会出现 一级页面还在抓取的时候,由于队列为空,直接退出的情况。不知该如何去做这个判断?另外不知以下代码这么写是否有其他的问题??

# coding:utf-8

import asyncio

import aiohttp


class Task(object):
    def __init__(self, info, priority):
        self.priority = priority
        self.info = info

    def __lt__(self, other):
        return self.priority < other.priority


class Spider(object):

    def __init__(self, loop=None):
        self.loop = loop
        conn = aiohttp.TCPConnector(limit=3)
        self.session = aiohttp.ClientSession(loop=loop, connector=conn)
        self.queue = asyncio.PriorityQueue()

    def start(self, page):
        task_info = {'callback': self.parse_1, 'page': page}
        return task_info

    async def set_item(self, task):
        pass

    async def fetch(self, task):
        await asyncio.sleep(2)
        task['callback'](task['page'])

    async def worker(self):
        while True:
            next_task = await self.queue.get()
            if next_task.info.get('type') == 'item':
                asyncio.ensure_future(self.set_item(next_task.info))
            else:
                asyncio.ensure_future(self.fetch(next_task.info))
            self.queue.task_done()

            # if self.queue.empty():
            #     await asyncio.sleep(1)
            #     if self.queue.empty():
            #         break

    def run(self):
        for page in range(1, 10):
            self.queue.put_nowait(Task(self.start(page), 0))

        self.loop.run_until_complete(self.worker())

    def close(self):
        if not self.session.closed:
            if self.session._connector_owner:
                self.session._connector.close()
            self.session._connector = None

    def parse_1(self, meta):
        print('parse_1-----', meta)
        for page in range(20, 30):
            task = {'callback': self.parse_2, 'page': page}
            self.queue.put_nowait(Task(task, 1))

    def parse_2(self, meta):
        print('parse2----', meta)
        for page in range(30, 40):
            task = {'callback': self.parse_3, 'page': page}
            self.queue.put_nowait(Task(task, 0))

    def parse_3(self, meta):
        print('parse3----', meta)


loop = asyncio.get_event_loop()
sp = Spider(loop=loop)
sp.run()
sp.close()

----------------------- 以下是精选回复-----------------------

答:我看别人写的是先把队列放到 redis 里,对 redis 进行判断从而进行开始或终止
答:woker 函数里别 while True;弄一个标记,如果为 True 继续,为 False 就停止,
答:加个 work in progress 标记
答:手机看的好难受,没看完,你试试 work 那里使用 wait_for 替换 ensure_future
答:判断任务队列用 join 而不是 empty
答:怎么贴的代码?
答:建议 aio+mq

DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
网站模板库 » 尝试用 aiohttp 写爬虫,但这么写不知道该怎么停止循环?

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情