Scrapy: как перестать запрашивать в случае 302?

Я использую Scrapy 2.4 для сканирования определенных страниц из списка start_urls. Каждый из этих URL-адресов имеет предположительно 6 страниц результатов, поэтому я запрашиваю их все.

Однако в некоторых случаях имеется только одна страница результатов, а все остальные страницы с разбивкой на страницы возвращают 302 на pn=1. В этом случае я не хочу следовать этому 302 и не хочу продолжать поиск страницы 3,4,5,6, а скорее переходить к следующему URL-адресу в списке.

Как выйти (продолжить) из этого цикла for в случае 302/301 и как не следовать этому 302?

def start_requests(self):
    for url in self.start_urls:
        for i in range(1,7): # 6 pages
            yield scrapy.Request(
                url=url + f'&pn = {str(i)}'
            )

def parse(self, request):

    # parse page
    ...

    # recognize no pagination and somehow exit the for loop
    if not response.xpath('//regex'): 
        # ... continue somehow instead of going to page 2
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
0
68
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Основная проблема вашего подхода заключается в том, что из start_requests мы не можем заранее знать, сколько существует действительных страниц.

Обычный подход для таких случаев
заключается в планировании запросов один за другим таким образом, а не в цикле:

class somespider(scrapy.Spider):
...
    def start_requests(self):
        ...
        for u in self.start_urls:
            # schedule only first page of each "query"
            yield scrapy.Request(url=u+'&pn=1', callback=self.parse)

    def parse(self, response):
        r_url, page_number = response.url.split("&pn = ")
        page_number = int(page_number)
        ....
        if next_page_exists:
            yield scrapy.Request(
            url = f'{r_url}&pn = {str(page_number+1)}',
            callback = self.parse)
       else:
           # something else
           ...

Я понимаю, однако это приводит к моей основной проблеме, которая у меня была: stackoverflow.com/questions/65423455/… Ваше решение очень похоже на мой первый подход, который привел к этому обходному пути, что привело к этой проблеме.

merlin 23.12.2020 21:43

Да. Я понимаю. example.html и example.thml?pn=1 могут иметь одинаковый вывод, однако эта реализация не имеет запроса на example.html и не будет отправлять запросы на одну и ту же страницу дважды.

Georgiy 23.12.2020 21:48

Большой! Это не только работает, но и помогло мне лучше понять, как работает Scrapy, чтобы я мог еще больше улучшить алгоритм. Спасибо!

merlin 23.12.2020 22:22

Другие вопросы по теме