如何基于Scrapy构建一个能永久运行的网络爬虫?

11

我想基于Scrapy构建一个网络爬虫,从多个新闻门户网站抓取新闻图片。我希望这个爬虫具备以下特点:

  1. 永久运行

    即定期重新访问某些门户页面以获取更新。

  2. 设置优先级

    给不同类型的URL分配不同的优先级。

  3. 多线程抓取

我已阅读Scrapy文档,但没有找到与我列出的内容相关的部分(可能我不够仔细)。有人知道如何做到这一点吗?或者只是给一些想法/例子。谢谢!

2个回答

12

Scrapy是一个用于爬取网站的框架,因此它旨在支持您的标准,但默认情况下不会为您自动完成所有任务;您可能需要对该模块进行一些熟悉才能完成某些任务。

  1. 无限运行由调用Scrapy的应用程序控制。您告诉蜘蛛要去哪里以及何时去那里。
  2. 设置优先级是调度中间件的工作,您需要创建并将其插入到Scrapy中。关于此的文档似乎有点不完整,我没有查看过代码 - 原则上该功能是存在的。
  3. Scrapy天生就是基于事件驱动的异步,这可能正是您所需要的:在请求A仍然未完成时可以满足请求B。底层连接引擎不会阻止您使用真正的多线程,但Scrapy不提供线程服务。

Scrapy是一个库,而不是应用程序。使用该模块的用户需要编写相当数量的代码。


在我看来,爬虫似乎只适用于“一次性”任务(只是指定抓取所有内容并退出)。所以你的意思是,如果我想要一个长时间运行的爬虫,我应该自己编写应用程序并调用爬虫来完成工作。在Scrapy中通过中间件或其他方式实现长时间运行的逻辑并不容易,对吗?谢谢! - superb
你可能可以在Spider Middleware层实现重新爬取逻辑,但是原语似乎不太适合它,我的直觉是你会把应用程序层逻辑推到演示层(如果我可以允许误用OSI术语)。 http://doc.scrapy.org/topics/spider-middleware.html - msw
1
您提供的调度程序中间件链接现在无法使用。 - William Kinaan

0
关于永久运行的要求,以下是一些详细信息。
您需要捕获signals.spider_idle信号,并在连接到该信号的方法中,需要抛出DontCloseSpider异常。当没有挂起请求时,spider_idle信号被发送到scrapy引擎, 默认情况下,蜘蛛将关闭。 您可以拦截此过程。
请参见下面的代码:
import scrapy
from scrapy.exceptions import DontCloseSpider
from scrapy.xlib.pydispatch import dispatcher

class FooSpider(scrapy.Spider):
    def __init__(self, *args, **kwargs):
        super(FooSpider, self).__init__(*args, **kwargs)
        dispatcher.connect(self.spider_idle, signals.spider_idle)

    def spider_idle(self):
        #you can revisit your portal urls in this method
        raise DontCloseSpider 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接