尝试用 aiohttp 写爬虫,但这么写不知道该怎么停止循环?
使用 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
0条评论