Как увеличить скорость сканирования Scrapy при наличии множества дублирующих ссылок - PullRequest
0 голосов
/ 28 января 2020

Я использую Scrapy, чтобы сканировать веб-сайт с миллионами страниц, за которыми мне нужно следить, и извлекать из него информацию.

В настоящее время сканер обрабатывает только двести страниц в минуту, и мне нужно ускорить его вверх.

Для каждой страницы сканер извлекает свои ссылки и следует за ними. Проблема в том, что на каждой странице около 600 ссылок, и большинство из них есть на всех страницах, и я думаю, что это является причиной того, что сканер вызывает функцию запроса для всех ссылок, даже если они дублируются.

Вот упрощенная версия моего кода:

def parse_data(self, response):
    item = URL() 
    outlinks_extrated = [l.url for l in LinkExtractor(allow_domains=self.allowed_domains, deny_extensions = self.reg_deny, unique=False, restrict_xpaths=self.xpath_outlinks, tags=self.tags, deny = self.regex_denied).extract_links(response)]
    for url in outlinks_extrated: 
        yield scrapy.Request(url, callback=self.parse_data) 
    item['url'] = response.request.url
    yield item 

Я уже пытался установить параллельные запросы и параллельные запросы для каждого домена, но не работал.

Кто-нибудь знает, почему это Ползать занимает много времени, и как я могу ускорить его?

1 Ответ

0 голосов
/ 28 января 2020

Если я правильно вас понял, одна из ваших проблем - дубликаты ссылок. Почему бы просто не проанализировать набор ссылок и не проверить все ссылки, которые вы собираетесь анализировать по этому набору? Вот что я имею в виду:

links_visited = set()

def parse_data(self, response):
    item = URL() 
    outlinks_extrated = [l.url for l in LinkExtractor(allow_domains=self.allowed_domains, deny_extensions = self.reg_deny, unique=False, restrict_xpaths=self.xpath_outlinks, tags=self.tags, deny = self.regex_denied).extract_links(response)]
    for url in outlinks_extrated:
        if url not in links_visited:
            yield scrapy.Request(url, callback=self.parse_data)
            links_visited.add(url)
    item['url'] = response.request.url
    yield item 

Таким образом, вы будете уверены, что не будете повторно посещать URL-адреса.

РЕДАКТИРОВАТЬ: Возможно, лучшим решением было бы создать экземпляр scrapy.Request один раз; таким образом, вы можете использовать параметр dont_filter (проверьте https://docs.scrapy.org/en/latest/topics/request-response.html для получения дополнительной информации; ваши запросы будут отфильтрованы по умолчанию, чтобы вы не посещали повторяющиеся URL-адреса).

...