Scrapy自定义DownloadMiddleware不尊重DOWNLOAD_DELAY

Ton*_*ang 5 python scrapy

我目前正在开发我的 CustomDownloadMiddleware。这主要是由于对网页下载有一定的控制需求。我的 CustomDownloadMiddleware 如下所示

class MySeleniumDownloadMiddleware:
    """Scrapy middleware handling the requests using selenium"""

    def __init__(self, driver):
        self.driver = driver
        self.cookies = self.driver.get_cookies()

    @classmethod
    def from_crawler(cls, crawler):
        """Initialize the middleware with the crawler settings"""

        driver = init_chromium(crawler.settings.get('SELENIUM_HOSTNAME'))
        login(driver, crawler.settings.get('MY_CREDENTIAL'))

        middleware = cls(driver=driver)

        crawler.signals.connect(middleware.spider_closed, signals.spider_closed)

        return middleware


    def process_request(self, request, spider):
        """Process a request using the selenium driver if applicable"""

        try:
            self.driver.get(request.url)
        except WebDriverException:
            self.driver = init_chromium(spider.settings.get('SELENIUM_HOSTNAME'))
            recover_cookie_to_driver(self.driver, self.cookies)
            self.driver.get(request.url)

        body = str.encode(self.driver.page_source)

        # Expose the driver via the "meta" attribute
        request.meta.update({'driver': self.driver})

        return HtmlResponse(
            self.driver.current_url,
            body=body,
            encoding='utf-8',
            request=request
        )


    def spider_closed(self):
        """Shutdown the driver when spider is closed"""
        try:
            self.driver.quit()
        except WebDriverException:
            pass
Run Code Online (Sandbox Code Playgroud)

在 github 中提出问题后,我发现问题是需要自定义下载中间件来自行处理下载延迟,建议使用可以在该文件中找到的插槽。但是,我未能找到下载中间件中使用的插槽的任何相关示例。

另外,值得一提的是,我的代码很大程度上受到scrapy-selenium的启发,并且发现了一个问题,该问题为下载延迟提供了潜在的解决方案,但是当我使用time.sleep(second)解决方案时,管道和蜘蛛的parse功能没有同时处理,这我认为该解决方案不可行。

是否有一种正确的方法来实现slot下载中间件,使其尊重下载延迟,并且不会妨碍同时处理管道和抓取的能力?如果是,那是什么?

Geo*_*giy 3

我想我找到了这种行为的原因。
您的请求似乎未到达使用下载器相关设置(包括DOWNLOAD_DELAY)的下载器方法。
一般情况下(根据scrapy 架构)会发生以下情况:

  1. 下载器中间件process_request修改请求并将请求发送到下载器。

    下载器:
    将请求分配给
    执行步骤 4 中的请求的下载器插槽(计算下载器相关设置)。
    收到响应->发送到process_response方法(scrapy架构方案的步骤5 )

  2. 下载器中间件process_request- 修改响应并将响应发送到engine.

您的具体情况的行为会有所不同:

  1. 下载器中间件将对象process_request发送到下载器(而不是请求)作为中间件方法的结果。下载器:不会执行请求 - 因为它已经收到上一步的响应。它将立即发送对方法的响应。 5.(同上)下载器中间件- 修改响应并 - 将响应发送到.Httpresponse
    process_request



    process_response

    process_requestengine

此行为编码为:

  • 下载器中间件管理器download方法。
  • Downloaderfetch方法(调用 DownloaderMiddlewareManager.download 的地方)

在 scrapy 下载器的当前实现中 -DOWNLOAD_DELAY和其他一些下载器相关的设置仅适用于非 selenium 请求。