Улучшение scrapy и селен с Firefox в безголовом режиме
Я очищаю тяжелый сайт на JavaScript и настроил бродячий экземпляр для проверки возможности ( 1 ГБ ОЗУ). Система падает после анализа нескольких URL-адресов. Я не могу определить требования к памяти для этой настройки и причину сбоя. Однако я запустил htop параллельно и получил скриншот перед сбоем системы, прикрепленный ниже. Я подозреваю, что памяти недостаточно, но я не знаю, сколько мне нужно. Поэтому я ищу:
- Требования к памяти для моей установки ( Scrapy + селен + fireofox - без головы
- Причина аварии
- Как улучшить процесс очистки
- Альтернативы любому из (scrapy, selenium, firefox)
SeleniumMiddleWare:
import os, traceback
from shutilwhich import which
from scrapy import signals
from scrapy.http import HtmlResponse
from scrapy.utils.project import get_project_settings
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.firefox.options import Options
SELENIUM_HEADLESS = False
settings = get_project_settings()
class SeleniumMiddleware(object):
driver = None
@classmethod
def from_crawler(cls, crawler):
middleware = cls()
crawler.signals.connect(middleware.spider_opened, signals.spider_opened)
crawler.signals.connect(middleware.spider_closed, signals.spider_closed)
return middleware
def process_request(self, request, spider):
if not request.meta.get('selenium'):
return
self.driver.get(request.url)
#if setting new cookies remove old
if len(request.cookies):
self.driver.implicitly_wait(1)
self.driver.delete_all_cookies()
#add only desired cookies if session persistence is requested
request_cookies=[]
if request.meta.get('request_cookies'):
request_cookies=request.meta.get('request_cookies')
for cookie in request.cookies:
if cookie['name'] in request_cookies:
print ' ---- set request cookie [%s] ---- ' % cookie['name']
new_cookie={k: cookie[k] for k in ('name', 'value','path', 'expiry') if k in cookie}
self.driver.add_cookie(new_cookie)
if request.meta.get('redirect_url'):
self.driver.get(request.meta.get('redirect_url'))
self.driver.implicitly_wait(5)
request.meta['driver'] = self.driver
return HtmlResponse(self.driver.current_url, body=self.driver.page_source, encoding='utf-8', request=request)
def spider_opened(self, spider):
options=Options()
binary= settings.get('SELENIUM_FIREFOX_BINARY') or which('firefox')
SELENIUM_HEADLESS=settings.get('SELENIUM_HEADLESS') or False
if SELENIUM_HEADLESS:
print " ---- HEADLESS ----"
options.add_argument( "--headless" )
firefox_capabilities = DesiredCapabilities.FIREFOX
firefox_capabilities['marionette'] = True
firefox_capabilities['binary'] = binary
try:
self.driver = webdriver.Firefox(capabilities=firefox_capabilities, firefox_options=options)
except Exception:
print " ---- Unable to instantiate selenium webdriver instance ! ----"
traceback.print_exc()
os._exit(1)
def spider_closed(self, spider):
if self.driver:
self.driver.close()
1 ответ
Быстрое проникновение в ваш блок кода показывает в def spider_closed(self, spider):
ты используешь self.driver.close()
следующее:
def spider_closed(self, spider):
if self.driver:
self.driver.close()
В соответствии с лучшими практиками, чтобы закрыть webdriver
вариант и webbrowser
Например, вы должны вызвать quit()
метод в пределах tearDown() {}
, Вызов quit()
, удаляет текущий сеанс просмотра, отправив quit
команда с {"flags":["eForceQuit"]}
и, наконец, отправляет запрос GET на /shutdown
EndPoint
,
Вы можете найти подробное обсуждение в разделе Как остановить процесс geckodriver, влияющий на память ПК, без вызова driver.quit()?
Таким образом, решение будет заменить self.driver.close()
с self.driver.quit()
следующее:
def spider_closed(self, spider):
if self.driver:
self.driver.quit()