python - Scrapy 自定义 DownloadMiddleware 不尊重 DOWNLOAD_DELAY
问题描述
我目前正在研究我的 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
在github打开一个issue后,发现问题是需要自定义下载中间件自己处理下载延迟,推荐使用这个文件中的slot 。但是,我没有找到下载中间件中使用的插槽的任何相关示例。
另外,值得一提的是,我的代码受到了scrapy-selenium的极大启发,并且发现了一个为下载延迟提供潜在解决方案的问题,但是当我使用time.sleep(second)
解决方案时,管道和蜘蛛的parse
功能没有同时处理,这我认为解决方案不可行。
是否有适当的方法在slot
下载中间件中实现,以尊重下载延迟,并且不会妨碍管道和抓取同时处理的能力?如果是,那是什么?
解决方案
我想我找到了这种行为的原因。
看起来您的请求未到达使用下载器相关设置(包括DOWNLOAD_DELAY
)的下载器方法。
在一般情况下(根据scrapy achitecture)会发生这种情况:
- Downloader 中间件
process_request
修改请求并 - 向 Downloader 发送请求。
下载器:将请求分配给从步骤 4 执行请求
的下载器插槽。(计算下载器相关设置)。收到响应 -> 发送到方法(scrapy 架构方案的第 5 步)process_response
- 下载器中间件
process_request
- 修改响应并 - 将响应发送到engine
.
你在你的情况下的行为会有所不同:
- 作为中间件方法的结果,下载器中间件
process_request
将Httpresponse
对象发送到下载器(而不是请求)。下载器:不会执行请求 - 因为它已经收到上一步的响应。它将立即向方法发送响应。 5.(同上)下载器中间件- 修改响应并 - 将响应发送到.process_request
process_response
process_request
engine
此行为编码为:
在目前的 scrapy 下载器实现中 -DOWNLOAD_DELAY
以及其他一些与下载器相关的设置仅适用于非 selenium 请求。
推荐阅读
- matlab - 使用 MATLAB 检测钢琴的音符
- sql - 合并 excel 文档中的多行,其中只有一列值与单行不同,将不同的值显示为不同的列
- flask - 在 Bokeh 应用和 Flask 应用之间共享端口
- python - 使用 TestCase 数据库的 DJANGO 开发服务器
- maven - Spring boot 2.0.1 应用程序不以 spring-cloud.version Finchley.RC1 开头,但与 Finchley.M9 一起工作正常
- c# - 即使编辑器显示错误并且 NuGet 包的安装失败,构建也会成功
- emr - PrestoDb 无法初始化类 sun.net.www.protocol.http.HttpURLConnection
- java - 无法在 Wildfly 10 服务器和 JaxR 上使用 HiveDrivers
- rest - 如何使用 Flask-restplus 从 PUT 请求中获取表单数据
- gradle - 从 Eclipse 中的 gradle 项目运行单个 JUnit 测试套件的问题