具有状态会话的 Scrapy 并发请求

aco*_*wpy 6 python session-cookies scrapy web-scraping scrapinghub

我已经有一段时间进行网络抓取,但对 python 来说相对较新,最近将我所有的抓取活动从 ruby​​ 切换到 python,主要是因为scrapy和scrapinghub似乎为大规模生产化抓取提供了更好的支持。

我在抓取电子商务网站时遇到的一个问题是,许多似乎使用“有状态”会话,即除非您发送从先前响应返回的相同 cookie,否则下一个请求可能会被阻止。特别是,许多使用IBM Websphere 的站点都表现出这种行为。

鉴于使用并发异步请求,这成为scrapy 的一个问题。

这些站点中的大多数都需要加载 JS 才能设置初始 cookie,因此我的方法是使用 Selenium(无头 chromedriver)加载初始页面,然后将 cookie 传递给普通的 scrapy 请求。

def __initialise_cookies(self):
        # Where self is the spider and driver is the Selenium driver instance
        self.session_cookies = self.driver.get_cookies()
Run Code Online (Sandbox Code Playgroud)

当 CONCURRENT_REQUESTS 在 scrapy 配置文件中设置为 1 时,这种方法完全正常。然而,这消除了所有并发性,显然会大大减慢刮擦速度。

我知道scrapy 已经发布了下载器中间件功能,允许在请求中命名cookiejar,然后传递给后续请求。我也读过这篇文章。然而,这似乎并没有解决我的问题 - 我只能假设是因为并发导致 cookiejar 被同时重复使用多次,即使您创建几个不同的 cookiejar 作为起点。

有没有人有关于如何解决这个问题的想法?

理想情况下,我想创建与 CONCURRENT_REQUESTS 设置(例如 16)相同数量的会话 cookiejar,但是我如何处理确保每个 cookiejar 一次最多只使用一次,然后将响应 cookie 传递给下一个请求。

我知道 Twisted 不使用线程,但是为 N 个 cookiejar 中的每一个创建一个信号量并使请求等待直到它未使用后再发送下一个请求是否有意义?