网页新闻抓取(2..parse异步爬虫实现的流程(2.1新闻源列表))

优采云 发布时间: 2021-10-21 15:14

  网页新闻抓取(2..parse异步爬虫实现的流程(2.1新闻源列表))

  urllib.parse:解析url网站的模块;

  logging:记录爬虫日志;

  leveldb:谷歌的Key-Value数据库,用于记录URL的状态;

  farmhash:对url进行hash计算,作为url的唯一标识;

  sanicdb:封装aiomysql,使数据库mysql操作更方便;

  2.异步爬虫实现过程2.1新闻来源列表

  本文要实现的异步爬虫是一个定向抓取新闻网站的爬虫,所以我们需要管理一个定向源列表,里面记录了很多我们想要的新闻网站的url抓住。这些 URL 指向的网页称为枢纽网页,它们具有以下特点:

  Hub网页是爬虫的起点,爬虫从中提取指向新闻页面的链接,然后对其进行爬取。Hub URL可以保存在MySQL数据库中,运维可以随时添加或删除这个列表;爬虫会定期读取这个列表,更新有针对性的爬虫任务。这需要爬虫中有一个循环来定期读取集线器 URL。

  2.2 网址池

  异步爬虫的所有进程都不是一个循环就能完成的,它是通过多个循环(至少两个)的交互来完成的。它们交互的桥梁是“URL 池”(使用 asyncio.Queue 实现)。

  这个 URL 池是熟悉的“生产者-消费者”模型。

  一方面,hub URL每隔一段时间就会进入URL池,爬虫从网页中提取的新闻链接也会进入URL池。这是生成 URL 的过程;

  另一方面,爬虫需要从URL池中取出URL进行下载。这个过程是一个消费过程;

  两个进程相互配合,URL不断进出URL池。

  2.3 数据库

  这里使用了两个数据库:MySQL 和 Leveldb。前者用于保存集线器 URL 和下载的网页;后者用于存储所有网址的状态(是否抓取成功)。

  从网页中提取出来的很多链接可能已经被爬取过,不需要再次爬取,所以在进入URL池之前必须进行检查,通过leveldb可以快速查看其状态。

  3. 异步爬虫的实现细节

  前面爬虫过程中提到了两个循环:

  周期一:定期更新hub网站列表

  async def loop_get_urls(self,):

print('loop_get_urls() start')

while 1:

await self.get_urls() # 从MySQL读取hub列表并将hub url放入queue

await asyncio.sleep(50)

  循环二:抓取网页的循环

  async def loop_crawl(self,):

print('loop_crawl() start')

last_rating_time = time.time()

asyncio.ensure_future(self.loop_get_urls())

counter = 0

while 1:

item = await self.queue.get()

url, ishub = item

self._workers += 1

counter += 1

asyncio.ensure_future(self.process(url, ishub))

span = time.time() - last_rating_time

if self._workers > self.workers_max:

print('got workers_max, sleep 3 sec to next worker')

await asyncio.sleep(3)

  4. asyncio 关键点:

  阅读 asyncio 的文档以了解其运行过程。以下是您在使用时注意到的一些要点。

  (1)使用loop.run_until_complete(self.loop_crawl())启动整个程序的主循环;

  (2)使用asyncio.ensure_future()异步调用一个函数,相当于gevent的多进程fork和spawn(),具体可以参考上面的代码。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线