Scrapy具有多个Selenium实例(并行)

时间:2019-01-23 00:58:29

标签: python selenium scrapy

我需要用SeleniumScrapy抓取许多网址。为了加快整个过程,我正在尝试创建一堆共享的Selenium实例。我的想法是要有一组Selenium可用的并行Request实例,如果需要,released可用。

我试图创建一个Middleware,但是问题是Middleware是顺序的(我看到所有驱动程序(我称其为浏览器)都在加载URL,并且似乎是顺序的)。我希望所有驱动程序并行工作。

class ScrapySpiderDownloaderMiddleware(object):
    BROWSERS_COUNT = 10

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.free_browsers = set(
            [webdriver.Chrome(executable_path=BASE_DIR + '/chromedriver') for x in range(self.BROWSERS_COUNT)])

    def get_free_browser(self):
        while True:
            try:
                return self.free_browsers.pop()
            except KeyError:
                time.sleep(0.1)

    def release_browser(self, browser):
        self.free_browsers.add(browser)

    def process_request(self, request, spider):
        browser = self.get_free_browser()

        browser.get(request.url)

        body = str.encode(browser.page_source)
        self.release_browser(browser)

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

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

我不喜欢您这样做的解决方案:

driver.get(response.url) 
parse方法中使用

,因为它会导致多余的请求。每个网址都被请求两次,这是我需要避免的。

例如,这个https://stackoverflow.com/a/17979285/2607447

你知道该怎么办吗?

2 个答案:

答案 0 :(得分:0)

我建议您考虑使用scrapy + docker。您可以一次运行多个实例

答案 1 :(得分:0)

正如@Granitosaurus建议的那样,Splash是一个不错的选择。我个人使用过Scrapy-splash-Scrapy负责并行处理,Splash负责网站渲染,包括JavaScript执行。