问题 如何构建基于Scrapy的Web爬虫永远运行?


我想构建一个基于Scrapy的网络爬虫来从几个新闻门户网站上获取新闻图片。我想这个爬虫是:

  1. 永远奔跑

    意味着它将定期重新访问一些门户页面以获取更新。

  2. 安排优先事项

    为不同类型的URL提供不同的优先级。

  3. 多线程获取

我已经阅读了Scrapy文档,但没有找到与我列出的相关的东西(也许我不够谨慎)。这里有人知道怎么做吗?或者只是给出一些关于它的想法/例子。谢谢!


13096
2018-02-28 04:07


起源



答案:


Scrapy是一个用于抓取网站的框架,因此,它旨在支持您的标准,但它不会为您提供开箱即用的舞蹈;对于某些任务,您可能需要相对熟悉该模块。

  1. 永远运行取决于您调用Scrapy的应用程序。你说 蜘蛛 去哪里以及何时去那里。
  2. 优先考虑的是工作 调度程序中间件 您必须创建并插入Scrapy。关于这个的文档似乎参差不齐,我没有看过代码 - 原则上功能就在那里。
  3. Scrapy本质上是, 从根本上是异步的 这可能是你想要的:请求B可以满足,而请求A仍然是未完成的。底层连接引擎不会阻止您 善意 多线程,但Scrapy不提供线程服务。

Scrapy是一个库,而不是一个应用程序。模块的用户需要进行大量的工作(代码)。


12
2018-02-28 04:47



谢谢!根据我的理解,Spiders似乎适用于“一次性”工作(只需抓取指定的所有内容并退出)。所以你的意思是如果我想要一个长时间运行的爬虫,我应该自己编写应用程序并调用蜘蛛来完成这项工作。通过中间件或其他东西在Scrapy中实现长时间运行的逻辑并不容易,对吧? - superb
您可能可以在Spider Middleware层中实现重新蜘蛛逻辑,但原语看起来并不适合它,而我的直觉是您将应用程序层逻辑推入表示级别(如果我可能被允许)滥用OSI术语)。 doc.scrapy.org/topics/spider-middleware.html - msw
您提供的调度程序中间件链接现在不起作用。 - William Kinaan


答案:


Scrapy是一个用于抓取网站的框架,因此,它旨在支持您的标准,但它不会为您提供开箱即用的舞蹈;对于某些任务,您可能需要相对熟悉该模块。

  1. 永远运行取决于您调用Scrapy的应用程序。你说 蜘蛛 去哪里以及何时去那里。
  2. 优先考虑的是工作 调度程序中间件 您必须创建并插入Scrapy。关于这个的文档似乎参差不齐,我没有看过代码 - 原则上功能就在那里。
  3. Scrapy本质上是, 从根本上是异步的 这可能是你想要的:请求B可以满足,而请求A仍然是未完成的。底层连接引擎不会阻止您 善意 多线程,但Scrapy不提供线程服务。

Scrapy是一个库,而不是一个应用程序。模块的用户需要进行大量的工作(代码)。


12
2018-02-28 04:47



谢谢!根据我的理解,Spiders似乎适用于“一次性”工作(只需抓取指定的所有内容并退出)。所以你的意思是如果我想要一个长时间运行的爬虫,我应该自己编写应用程序并调用蜘蛛来完成这项工作。通过中间件或其他东西在Scrapy中实现长时间运行的逻辑并不容易,对吧? - superb
您可能可以在Spider Middleware层中实现重新蜘蛛逻辑,但原语看起来并不适合它,而我的直觉是您将应用程序层逻辑推入表示级别(如果我可能被允许)滥用OSI术语)。 doc.scrapy.org/topics/spider-middleware.html - msw
您提供的调度程序中间件链接现在不起作用。 - William Kinaan


关于永远跑步的要求,这里有一些细节。

你需要赶上 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 

0
2017-08-18 03:30