我需要用Selenium
和Scrapy
抓取许多网址。为了加快整个过程,我正在尝试创建一堆共享Selenium
实例。我的想法是,如果需要,为任何Request
提供一组并行Selenium
实例,如果完成,则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
方法,因为它会导致冗余请求。每个 url 都被请求两次,我需要避免。
例如,此 https://stackoverflow.com/a/17979285/2607447
你知道该怎么做吗?
我建议你看看 scrapy + docker。 您可以一次运行多个实例
正如@Granitosaurus所建议的,Splash是一个不错的选择。我个人使用Scrapy-splash - Scrapy
负责并行处理,Splash
负责网站渲染,包括JavaScript
执行。