Приоритет запроса Scrapy / Python и CONCURRENT_REQUESTS - PullRequest
1 голос
/ 10 апреля 2019

Я очищаю один домен, который имеет один IP. Он содержит список URL-адресов магазинов, а каждый URL-адрес магазина имеет список продуктов (многостраничный)

Сначала я просматриваю URL магазинов и выдаю запросы, назначая приоритет, который становится меньше для каждого магазина. Магазин 1 получает -1, Магазин 2 получает -2 и т. Д.

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

Это все работает нормально, если установлены CONCURRENT_REQUESTS. Я получаю URL с приоритетом -1 и -2, загруженные один за другим. Scrapy не переходит на URL с приоритетом -3 или ниже.

Тем не менее, я попытался CONCURRENT_REQUESTS_PER_DOMAIN и CONCURRENT_REQUESTS_PER_IP, и эти URL заканчиваются загрузкой с приоритетом -1, -2, -3, -4.

Я хотел бы понять, почему CONCURRENT_REQUESTS работают не так, как опции ...PER_DOMAIN и ...PER_IP, поскольку я загружаю из одного домена с одним IP-адресом.

Кто-нибудь может объяснить это?

Вот пример кода, чтобы увидеть, как он терпит неудачу:

from scrapy.spiders import Spider, Request
import scrapy
import logging

class MySpider(Spider):

    custom_settings = {
        'DEPTH_STATS_VERBOSE': True,
#        'CONCURRENT_REQUESTS': 1,
        'CONCURRENT_REQUESTS_PER_DOMAIN': 1,
        'CONCURRENT_REQUESTS_PER_IP': 1,
        'AUTOTHROTTLE_TARGET_CONCURRENCY': 1,
    }

    name = 'toscrapecom'
    start_urls = ['http://books.toscrape.com/catalogue/page-1.html']

    urls1 = (
        'http://books.toscrape.com/catalogue/page-{}.html'.format(i + 1) for i in range(5)
    )

    urls2 = (
        'http://books.toscrape.com/catalogue/page-{}.html'.format(i + 1) for i in range(5,10)
    )

    def parse(self, response):
        reqPriority = 20
        for url in self.urls1:
            yield Request(url,priority=reqPriority,callback=self.next_page)
            logging.info("%s Priority %s URL %s", self.name, reqPriority, url)
            reqPriority = reqPriority - 1

    def next_page(self,response):
        reqPriority = 40
        for url in self.urls2:
            yield Request(url,priority=reqPriority)
            logging.info("%s Priority %s URL %s", self.name, reqPriority, url)
            reqPriority = reqPriority - 1

1 Ответ

2 голосов
/ 14 апреля 2019

Приоритет запроса не гарантирует порядок.

Если у вас есть 16 запросов, каждый с различным приоритетом, и CONCURRENT_REQUESTS_PER_DOMAIN из 16, все 16 запросов отправляются почти одновременно, и они анализируются в порядке их поступления с сервера, что вряд ли соответствовать их значению приоритета.

CONCURRENT_REQUESTS и CONCURRENT_REQUESTS_PER_DOMAIN фактически работают в комбинации. CONCURRENT_REQUESTS_PER_DOMAIN по умолчанию равно 8, и не определение CONCURRENT_REQUESTS_PER_DOMAIN эквивалентно определению его с 8 в качестве значения. Если вы видите другое поведение при установке CONCURRENT_REQUESTS_PER_DOMAIN, это должно быть потому, что вы использовали значение, отличное от 8.

CONCURRENT_REQUESTS_PER_IP, это отличается от CONCURRENT_REQUESTS_PER_DOMAIN, как следует из названия. Если определено, значение CONCURRENT_REQUESTS_PER_DOMAIN игнорируется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...