我从事网络抓取已经有一段时间了,但对 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()
当在 scrapy 配置文件中将 CONCURRENT_REQUESTS 设置为 1 时,这种方法完全可以正常工作。然而,这消除了所有并发性,显然大大减慢了抓取速度。
我知道scrapy 已经发布了下载器中间件功能,允许在请求中命名cookiejar,然后传递给后续请求。我也读过这篇文章。然而,这似乎并不能解决我的问题 - 我只能假设因为并发性会导致 cookiejar 同时重复使用多次,即使您创建几个不同的 cookiejar 作为起点也是如此。
有人对如何解决这个问题有想法吗?
理想情况下,我想创建与 CONCURRENT_REQUESTS 设置(例如 16)相同数量的会话 cookiejars,但是如何确保每个 cookiejar 一次最多使用一次,然后将响应 cookie 传递给下一个请求。
我知道 Twisted 不使用线程,但是为 N 个 cookiejar 中的每一个创建一个信号量并让请求等到它未使用后再发送下一个请求是否有意义?