Как уменьшить количество экземпляров селена вебдрайвера, порождаемых scrapy при запуске сканирования на пауке? - PullRequest
0 голосов
/ 16 апреля 2020

При запуске процесса сканирования для любого паука Scrapy имеет тенденцию порождать много (27 в среднем варьируется от 19 до 30) Firefox случаев, даже если бегущий паук не использует селен.

I попробовал driver.quit() внутри def __del__(self) в каждом из пауков, используя селен. Проблема все еще сохраняется.

Экземпляры Firefox остаются открытыми даже после завершения процесса сканирования.

Пример паука с использованием селена:

import logging
import time
from os.path import abspath, dirname, join
import requests
import scrapy
import selenium
from scrapy.http import HtmlResponse
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.remote.remote_connection import LOGGER
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait

LOGGER.setLevel(logging.ERROR)

PATH_DIR = dirname(abspath(__file__))
GECKODRIVER_PATH = abspath(join(PATH_DIR, "../../geckodriver"))
WAIT_TIME = 10

class ExampleSpider(sso_singapore.SsoSpider):

    name = "Example"

    options = Options()
    options.headless = True
    driver = webdriver.Firefox(options=options, executable_path=GECKODRIVER_PATH)

    def __del__(self):
        self.driver.quit()

    def parse(self, response):

        meta = response.meta
        try:
            self.driver.get(response.url)
            body = self.driver.page_source
            try:
                element = WebDriverWait(self.driver, WAIT_TIME).until(
                    EC.presence_of_element_located(
                        (By.ID, '//select[@id="rows_sort"]/option[text()="All"]')
                    )
                )
            except:
                pass
            response = HtmlResponse(
                self.driver.current_url, body=body, encoding="utf-8"
            )

        except Exception as e:
            logging.error(str(e))
        finally:
            self.driver.quit()
       # Create Items based on response

    def start_requests(self):

        for url, meta in zip(urls, meta_list):
            yield scrapy.Request(url, callback=parse, meta=meta)


Любая помощь будет высоко оценена.

1 Ответ

2 голосов
/ 16 апреля 2020
from scrapy import signals

class ExampleSpider(sso_singapore.SsoSpider):

    def __init__(self, *args, **kwargs):
        options = Options()
        options.headless = True
        self.driver = webdriver.Firefox(options=options, executable_path="your_path")

    @classmethod
    def from_crawler(cls, crawler, *args, **kwargs):
        spider = super(ExampleSpider, cls).from_crawler(crawler, *args, **kwargs)
        crawler.signals.connect(spider.spider_closed, signal=signals.spider_closed)
        return spider

    def spider_closed(self, spider):
        self.driver.quit()

Это должно сделать работу.

Подробнее о сигналах Scrapy:

https://docs.scrapy.org/en/latest/topics/signals.html

Вы также можете использовать Pipeline, если у вас много пауков и вы не хотите добавлять один и тот же driver.quit() logi c:

class YourPipeline:

    @classmethod
    def from_crawler(cls, crawler):
        pipeline = cls()
        crawler.signals.connect(pipeline.spider_closed, signals.spider_closed)
        return pipeline

    def spider_closed(self, spider):
        if hasattr(spider, 'driver'):
            spider.driver.quit()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...