Как сделать цикл завершения и только потом запустить функцию скрапа - PullRequest
0 голосов
/ 28 октября 2019

У меня есть простой класс паука с двумя функциями. Один для получения ссылок со стартовой страницы и ввода их (также - для получения ссылки на следующую страницу), другой - для анализа каждой ссылки (страницы, на которую она ведет). Проблема в том, что у меня есть цикл for, который перебирает ссылки и выдает scrapy.Request для каждой из них, а после этого для цикла у меня есть оператор if, чтобы проверить, является ли текущая страница последней, если нет -- Я хочу выдать первую функцию со ссылкой на следующую страницу, если да, - чтобы остановить паука и сказать «Последняя страница, приятель!».

def parse(self, response):

    links = response.xpath('//tags_to_be_chosen/@href').getall()

    next_page = response.xpath('//tag_to_be_chosen/@href').get()

    check = response.xpath('//tag_to_be_chosen/text()').get()

    for link in links:
        yield scrapy.Request(response.urljoin(link.strip()), callback=self.parse_page)

    if 'specific_string_is' in check: # go to next page, but only after for loop has finished its job
        yield scrapy.Request(response.urljoin(next_page.strip()), callback=self.parse)
    else: # stop the crawler, because we've reached the last page
        print('We\'ve reached the last page!')

def parse_page(self, response):

    with open('file_to_write', 'a') as file: # when there's a table of items to be crawled (different tags used than for a single item)
        for item in response.xpath('//tags_to_be_chosen/text()').getall():
            file.write('{}\n'.format(item.strip()))
        else: # when there's a single item to be crawled (different tag used than for multiple items
            item = response.xpath('//tag_to_be_chosen').get()
            item = item.strip()
            item = re.sub('sth_to_be_deleted', '', item)
            file.write('{}\n'.format(item))

Ожидаемый результат - дождаться цикла forзавершает вызов функции № 2 (ввод и разбор всех ссылок) и только затем вводит ссылку на следующую страницу. По какой-то причине if проверяется, в то время как for все еще проходит по ссылкам, вызывается функция для анализа следующей страницы (что означает изменение ссылок), и процесс начинается для новых ссылок, не заканчивая "старые".


БОЛЬШОЕ РЕДАКТИРОВАНИЕ СДЕЛАНО, как указано в комментариях:

1 Ответ

0 голосов
/ 28 октября 2019

Почему именно вы используете урожай? этот метод был повторен внешне? Последний IF будет вызван после выполнения внешней итерации, но похоже, что вы выполняете локальную переменную links. Вам, вероятно, здесь не нужен доход.

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

Для удаления ссылки это можно сделать двумя способами: последовательным или параллельным.

  • Для последовательного интерфейса вы просто выполняете цикл for, вызывающий запрос с его обратным вызовом
  • . Для параллельного выполнения вам понадобится пул потоков, отправляющий обработку каждой ссылки в поток, а после цикла for присоедините пул кдождитесь всех потоков, а затем вызовите функцию 2.
...