我需要用Selenium
和Scrapy
抓取许多网址。为了加快整个过程,我正在尝试创建一堆共享的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
你知道该怎么办吗?
答案 0 :(得分:0)
我建议您考虑使用scrapy + docker。您可以一次运行多个实例
答案 1 :(得分:0)
正如@Granitosaurus建议的那样,Splash是一个不错的选择。我个人使用过Scrapy-splash-Scrapy
负责并行处理,Splash
负责网站渲染,包括JavaScript
执行。