使用 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()
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.