Производительность трубопровода Scrapy - PullRequest
0 голосов
/ 05 ноября 2019

В настоящее время я использую Scrapy для личного проекта, но борюсь за аспект производительности.

Когда я не использую конвейер, мои 4 симулятивных сканера могут сканировать 600 страниц за 30 секунд.

Я реализовал собственный конвейер для обработки сценариев на каждой странице и сравнения их со списком из 5000 URL-адресов, чтобы проверить, существует ли URL-адрес в коде сценария.

Проблема заключается в том, чтоэто заставляет мой обход работать в течение 110 секунд вместо 30 секунд, когда я не использую конвейер.

Мне интересно, как я могу оптимизировать свой код, учитывая, что для каждой страницы я проверяю каждую измоя ссылка через все мои скрипты.

Ниже показано, как это выглядит:

Можем ли мы запустить многопоточность для ускорения циклов?

Функция анализа в классе паука:

    def parse(self, response):

    print('### SCANNED: %s', (response.request.url))

    if len(response.css('script').getall()) > 0:

        yield {
            'domain': response.meta['domain'],
            'scripts': response.css('script').getall()
        }

Функция элемента процесса в конвейере

    def process_item(self, item, spider):

    domain = item['domain']
    scripts = item['scripts']

      for script in scripts: # There are about 15 scripts per item

        for script_group in self.script_groups: # There are about 5000 script_groups

            # Check all urls in script_group to see if script_group is being used

            for url in script_group['urls']: # There are about 2 urls per script_group
                # If at least one url found then script_group is being used

                if url in script:

                    print("url found, script_group is being used")
                    break

    return item

1 Ответ

1 голос
/ 06 ноября 2019

Попробуйте избегать такого количества циклов for.

Например:

  1. Создать объект регулярного выражения в конвейере __init__ метод из self.script_groups:
    self.url_re = re.compile(
        '(?:{})'.format(
            '|'.join(
                re.escape(url)
                for url in group['urls']
                for group in self.script_groups
            )
        )
    )
Используйте это:
    for script in scripts:
        if self.url_re.search(script):
            print("url found, script_group is being used")
            break
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...