Оригинальный пост Python Scraphy Учебник для начинающих – 03 – Как перейти на следующую страницу
На нашем последнем уроке Извлечение всех данных с помощью Scrapy, Нам удалось получить все книги URL, а затем извлекли данные из каждого. Мы были ограничены книгами на главной странице, так как мы не знали, как перейти на следующую страницу с помощью Scrapy.
До сих пор.
В этом посте вы узнаете, как:
- Перейдите на следующую страницу ‘
- Решать проблемы маршрутизации
- Извлечь все данные каждой доступной книги
Наш игровой план
Первоначально мы только что перечислили все URL-адреса книги, а затем, один за другим, мы извлекли данные.
Поскольку у нас было 20 книг, мы только что перечислили 20 URL-адресов книг, а затем анализируют эти 20 URL-адресов, уступив результат.
Нам просто нужно добавить еще один шаг.
Теперь мы перейду 20 URL-адресов книги, анализируйте их, а затем, если есть «следующая» страница, мы найдут к нему, чтобы повторить процесс, перечисление и получение новых 20 книжных URL, пока не больше нет страницы.
В нашем Красивый суп Учебник Мы использовали такую же стратегию:
И это то, что мы собираемся начать использовать прямо сейчас.
Проверка, доступна ли «следующая страница»
Давайте начнем с кода, который мы использовали на нашем втором уроке, Извлечь все данные :
# -*- coding: utf-8 -*- import scrapy class SpiderSpider(scrapy.Spider): name = 'spider' allowed_domains = ['books.toscrape.com'] start_urls = ['http://books.toscrape.com/'] base_url = 'http://books.toscrape.com/' def parse(self, response): all_books = response.xpath('//article[@class="product_pod"]') for book in all_books: book_url = self.start_urls[0] + book.xpath('.//h3/a/@href').extract_first() yield scrapy.Request(book_url, callback=self.parse_book) def parse_book(self, response): title = response.xpath('//div/h1/text()').extract_first() relative_image = response.xpath('//div[@class="item active"]/img/@src').extract_first() final_image = self.base_url + relative_image.replace('../..', '') price = response.xpath( '//div[contains(@class, "product_main")]/p[@class="price_color"]/text()').extract_first() stock = response.xpath( '//div[contains(@class, "product_main")]/p[contains(@class, "instock")]/text()').extract()[1].strip() stars = response.xpath( '//div/p[contains(@class, "star-rating")]/@class').extract_first().replace('star-rating ', '') description = response.xpath( '//div[@id="product_description"]/following-sibling::p/text()').extract_first() upc = response.xpath( '//table[@class="table table-striped"]/tr[1]/td/text()').extract_first() price_excl_tax = response.xpath( '//table[@class="table table-striped"]/tr[3]/td/text()').extract_first() price_inc_tax = response.xpath( '//table[@class="table table-striped"]/tr[4]/td/text()').extract_first() tax = response.xpath( '//table[@class="table table-striped"]/tr[5]/td/text()').extract_first() yield { 'Title': title, 'Image': final_image, 'Price': price, 'Stock': stock, 'Stars': stars, 'Description': description, 'Upc': upc, 'Price after tax': price_excl_tax, 'Price incl tax': price_inc_tax, 'Tax': tax, }
Поскольку это в настоящее время работает, нам просто нужно проверить, есть ли «следующая» кнопка после завершения цикла. Щелкните правой кнопкой мыши на следующей кнопке:
Следующая страница URL находится внутри А Тег, в пределах Ли тег. Вы знаете, как их извлечь, так что создайте _next_page_url _ Мы можем перейти к. Остерегайтесь, это частичный URL, поэтому вам нужно добавить базовый URL. Как мы это сделали раньше, вы можете сделать это самостоятельно. Дайте это попробовать.
Вот как я это сделал:
for book in all_books: book_url = self.start_urls[0] + book.xpath('.//h3/a/@href').extract_first() yield scrapy.Request(book_url, callback=self.parse_book) # New code: next_page_partial_url = response.xpath( '//li[@class="next"]/a/@href').extract_first() next_page_url = self.base_url + next_page_partial_url yield scrapy.Request(next_page_url, callback=self.parse)
Запустите код с Scrapy Crawl Spider-o next_page.json и проверьте результат.
Что происходит? В файле только 20 элементов! Давайте проверим журнал, чтобы увидеть, что происходит.
Нам удалось получить первые 20 книг, но вдруг, мы не можем получить больше книг …
books.toscrape.com это сайт, сделанный Скаубинг хаб Для обучения людей на веб-соскобе, и у них мало ловушек, которые вам нужно заметить. Сравните успешные URL-адреса (синий подчеркивание) с неудачными (красными подчеркиванием). Есть _/каталог _миссинг на каждой маршрутизации. Они не добавляли его, чтобы заставить вас терпеть неудачу.
Давайте решим эту проблему.
Решение проблемы маршрутизации «книги»
Как /каталог Отсутствует от некоторых URL-адресов, давайте проверим чек: если не имеет его маршрута, давайте префиксирую его к частичному URL. Так просто.
Попробуйте его самостоятельно, прежде чем продолжить. Вы можете проверить свой код здесь:
for book in all_books: book_url = book.xpath('.//h3/a/@href').extract_first() if 'catalogue/' not in book_url: book_url = 'catalogue/' + book_url book_url = self.base_url + book_url
Давайте запустим код еще раз! Это должно работать, верно? Scrapy Crawl Spider-o next_page.json
Теперь у нас больше книг! Но только 40. Нам удалось получить первые 20, то следующие 20. Тогда что-то случилось. Мы не получили третью страницу со второго. Пойдем на вторую страницу и посмотрите, что происходит с следующей кнопкой и сравните его с первым (и его ссылкой на второй)
У нас такая же проблема, которую мы имели с книгами: некоторые ссылки имеют /каталог Некоторые другие нет.
Решение проблемы «Далее» проблема маршрутизации
Как у нас такая же проблема, у нас есть одно и то же решение. Один вы можете легко решить. Почему бы тебе не попробовать? Опять же, вам просто нужно проверить ссылку и префикс /Каталог В случае, если подкрутка не там.
Если бы вы не могли решить это, это мое решение:
next_page_partial_url = response.xpath( '//li[@class="next"]/a/@href').extract_first() if next_page_partial_url: if 'catalogue/' not in next_page_partial_url: next_page_partial_url = "catalogue/" + next_page_partial_url next_page_url = self.base_url + next_page_partial_url yield scrapy.Request(next_page_url, callback=self.parse)
Вы можете увидеть шаблон: мы получаем частичный URL, проверим Если /каталог отсутствует, и если это так, мы добавляем его. Затем мы добавляем base_url, и у нас есть наш абсолютный URL.
Запустите паука снова: Scrapy Crawl Spider-o next_page.json Отказ
Теперь у нас есть 1000 книг. Каждый из. 🙂
Это последний код:
# -*- coding: utf-8 -*- import scrapy class SpiderSpider(scrapy.Spider): name = 'spider' allowed_domains = ['books.toscrape.com'] start_urls = ['http://books.toscrape.com/'] base_url = 'http://books.toscrape.com/' def parse(self, response): all_books = response.xpath('//article[@class="product_pod"]') for book in all_books: book_url = book.xpath('.//h3/a/@href').extract_first() if 'catalogue/' not in book_url: book_url = 'catalogue/' + book_url book_url = self.base_url + book_url yield scrapy.Request(book_url, callback=self.parse_book) next_page_partial_url = response.xpath( '//li[@class="next"]/a/@href').extract_first() if next_page_partial_url: if 'catalogue/' not in next_page_partial_url: next_page_partial_url = "catalogue/" + next_page_partial_url next_page_url = self.base_url + next_page_partial_url yield scrapy.Request(next_page_url, callback=self.parse) def parse_book(self, response): title = response.xpath('//div/h1/text()').extract_first() relative_image = response.xpath( '//div[@class="item active"]/img/@src').extract_first() final_image = self.base_url + relative_image.replace('../..', '') price = response.xpath( '//div[contains(@class, "product_main")]/p[@class="price_color"]/text()').extract_first() stock = response.xpath( '//div[contains(@class, "product_main")]/p[contains(@class, "instock")]/text()').extract()[1].strip() stars = response.xpath( '//div/p[contains(@class, "star-rating")]/@class').extract_first().replace('star-rating ', '') description = response.xpath( '//div[@id="product_description"]/following-sibling::p/text()').extract_first() upc = response.xpath( '//table[@class="table table-striped"]/tr[1]/td/text()').extract_first() price_excl_tax = response.xpath( '//table[@class="table table-striped"]/tr[3]/td/text()').extract_first() price_inc_tax = response.xpath( '//table[@class="table table-striped"]/tr[4]/td/text()').extract_first() tax = response.xpath( '//table[@class="table table-striped"]/tr[5]/td/text()').extract_first() yield { 'Title': title, 'Image': final_image, 'Price': price, 'Stock': stock, 'Stars': stars, 'Description': description, 'Upc': upc, 'Price after tax': price_excl_tax, 'Price incl tax': price_inc_tax, 'Tax': tax, }
Вывод
Вы сегодня ударили милон. Теперь вы можете извлечь каждый элемент с сайта.
Вы узнали, что вам нужно получить все элементы на первой странице, ломайте их индивидуально, и как перейти на следующую страницу, чтобы повторить этот процесс. Позвольте мне еще раз показать диаграмму:
И не только это. Этот пример был сложным, поскольку мы должны были проверить, имел ли частичный URL /каталог добавить его.
Обычно Paginating веб-сайты с Scrapy проще, поскольку кнопка «Далее» содержит полный URL, поэтому этот пример был еще сложнее, чем обычно, и все же вам удалось получить его!
Но … Что, если я скажу вам, что это может быть еще проще, чем то, что мы сделали?
Вместо того, чтобы схватить свой вилы и направиться к моему дому, иди к Четвертый урок Где вы узнаете, как соскребать каждый элемент еще более простым способом, используя ползунки.
Мои учебные видеоролики YouTube
Окончательный код на GitHub
Добраться до меня в Twitter
Предыдущий урок: 02 – Создание вашего первого паука
Оригинал: “https://dev.to/davidmm1707/how-to-go-to-the-next-page-03-python-scrapy-tutorial-for-beginners-33if”