500lines之crawler学习(五)

前面几篇文章主要是分析改错,这篇文章来分析下,这个爬虫是怎么运作的。核心就在crawling.py文件中,这个文件的代码稍微有点乱,不是很容易看明白,下面把重要代码贴不出:

#初始化
self.q = Queue(loop=self.loop)
....
self.q.put_nowait((url, max_redirect))
....
def fetch(self, url, max_redirect):
    ...
    self.q.put_nowait((link, self.max_redirect))
    ...
def work(self):
    """Process queue items forever."""
    while True:
        url, max_redirect = yield from self.q.get()
        yield from self.fetch(url, max_redirect)
        self.q.task_done()
....
def crawl(self):
    """Run the crawler until all finished."""
    workers = [asyncio.Task(self.work(), loop=self.loop)
               for _ in range(self.max_tasks)]
    self.t0 = time.time()
    yield from self.q.join()
    self.t1 = time.time()
    for w in workers:
        w.cancel()

核心调度过程就是上面的代码,通过crawl()方法启动——创建Task——把work()方法加入创建的Task——在work()方法中获取初始化地址并开始抓取。

500lines之crawler学习(五)_第1张图片

关于队列Queue的用法,见下文:

Python之asyncio.Queue

上图代码中,稍微难理解的是crawl()方法中,有句:

...
yield from self.q.join()
...

这是一句突然冒出来的代码,它的作用是等待queue中所有的数据被处理(由queue.task_done()通知),而work()方法里面正好是调用task_done()的地方,所以q.join()的作用就是等待work()方法中的所有task_done()调用完成。

你可能感兴趣的:(python,python)