CoderCastrov logo
CoderCastrov
Питон

Начало работы с Scrapy: веб-парсер на основе скриптов на Python

Начало работы с Scrapy: веб-парсер на основе скриптов на Python
просмотров
5 мин чтение
#Питон

Привет всем, давайте создадим простой веб-парсер, используя фреймворк для парсинга веб-страниц на Python - "Scrapy".

Обзор Scrapy

Scrapy - это фреймворк на Python для масштабированного парсинга веб-страниц. Scrapy построен на асинхронном сетевом движке Twisted, что означает, что он не использует стандартную инфраструктуру асинхронности/ожидания в Python. Twisted - это событийно-ориентированный сетевой движок, написанный на Python. Он позволяет Scrapy обрабатывать запросы и ответы асинхронно, назначая каждый входящий запрос "реактору", который ожидает ответа. Это позволяет Scrapy обрабатывать несколько запросов одновременно, улучшая его производительность и эффективность.

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

XPATH

XPath - это язык запросов, который используется для выбора элементов из XML-документа, такого как HTML-страница. Он предоставляет способ навигации по иерархии документа и поиска элементов, которые соответствуют определенному набору критериев, таких как атрибуты элемента или его положение в документе.

Вот несколько простых примеров выражений XPath:

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

CSS Selectors

Как и XPATH, CSS-селекторы также используются для выбора элементов на HTML-странице. CSS-селекторы используют синтаксис языка Cascading Style Sheets (CSS) для указания элементов, которые вы хотите выбрать. Например, вы можете использовать CSS-селектор для выбора всех элементов <h1> на странице, всех элементов с классом title или всех элементов с идентификатором main-content.

Вот несколько примеров CSS-селекторов, которые вы можете использовать в проекте по парсингу:

  • h1: Этот селектор выбирает все элементы <h1> на странице.
  • .title: Этот селектор выбирает все элементы с классом title.
  • #main-content: Этот селектор выбирает элемент с идентификатором main-content.
  • a[href]: Этот селектор выбирает все элементы <a>, у которых есть атрибут href.
  • table tr:nth-child(2) td:nth-child(3): Этот селектор выбирает третий элемент <td> второго элемента <tr> внутри <table>.

Это всего лишь несколько примеров из множества различных CSS-селекторов, которые вы можете использовать при парсинге. Чтобы узнать больше о CSS-селекторах и о том, как их использовать, вы можете обратиться к документации библиотеки или фреймворка для парсинга, которые вы используете.

**СОВЕТ: **CSS-селекторы работают быстрее, чем выражения XPath для выбора элементов на веб-странице. Это связано с тем, что большинство современных веб-браузеров, включая Google Chrome и Mozilla Firefox, используют оптимизированные алгоритмы для быстрого вычисления CSS-селекторов и поиска соответствующих элементов на странице.

Scrapy Shell

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

Чтобы запустить оболочку Scrapy, мы должны ввести эту команду в командной строке или терминале:

scrapy shell

после ввода вышеуказанной команды терминал будет выглядеть так:

Теперь нам нужно указать URL веб-сайта, который мы хотим спарсить и протестировать в оболочке Scrapy. Для этого команда будет следующей:

fetch("URL")

В нашем случае мы будем парсить этот веб-сайт: https://beutlich.com/products/. поэтому команда будет выглядеть так:

fetch("https://beutlich.com/products/")

Обратите внимание, что код ответа 200. Это означает, что мы успешно обработали введенный URL.

После обработки URL теперь нам нужно спарсить доступные URL-адреса продуктов. Если мы проверим URL-адреса продуктов, они доступны в теге якоря, который находится внутри тега статьи. См. скриншот ниже

поэтому мы можем составить XPATH следующим образом: //article[contains(@class, 'portfolio-item count')]/a/@href

В нашей оболочке Scrapy мы напишем команду для извлечения URL:

response.xpath("//article[contains(@class, 'portfolio-item count')]/a/@href").extract()

Это вернет нам список URL-адресов различных доступных продуктов.

Теперь мы можем получить URL-адреса продуктов, поэтому мы можем, наконец, спарсить информацию о продукте.

Теперь мы отправим другой запрос на спарсенные URL-адреса и получим ответ. В нашем коде Python мы напишем отдельную функцию для этого и передадим ответ каждого URL-адреса по одному этой функции.

Но пока мы протестируем наш код на одном URL в оболочке Scrapy.

Теперь мы хотим спарсить название продукта, которое доступно внутри тега h1, и у тега h1 нет класса, но мы можем получить доступ к этому тегу с помощью идентификатора тега заголовка. Так что XPATH будет выглядеть так:

//header[@id='page-heading']/h1/text()

и команда Scrapy

response.xpath("//header[@id='page-heading']/h1/text()").extract_first()

Обратите внимание: важно отметить, что extract() вернет список всех соответствующих результатов, тогда как extract_first() вернет только первый результат в виде строки.

Для парсинга артикула продукта код Scrapy будет выглядеть так.

response.css(".entry ul li:nth-child(8)::text").get().split(": ")[1]

Для парсинга описания продукта код Scrapy будет выглядеть так

response.css(".entry ::text").getall()

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

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

response.css(".slide>a::attr(href)").get()

Теперь перейдем к коду Python.

Сначала мы импортируем scrapy и его необходимые функции

import scrapy 
from scrapy.crawler import CrawlerProcess

Теперь мы определим наш класс парсера и внутри этого класса определим некоторые переменные класса.

class beutlich_scraper(scrapy.Spider):
    
    custom_settings = {
        'DOWNLOAD_DELAY' : 0.25,
        'RETRY_TIMES': 10,
        # экспорт в формате CSV
        'FEED_FORMAT' : 'csv',
        'FEED_URI' : 'Beutlich-data.csv'
        'OBEY_ROBOTS' : False,
    }
     
    start_urls =['https://beutlich.com/products/']

Custom_settings: для определения некоторых пользовательских настроек при отправке запросов на URL.

start_urls: это наш начальный URL.

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

def parse(self, response):
       links =response.xpath("//article[contains(@class, 'portfolio-item count')]/a/@href").extract()
        
        
      for link in links:
          yield scrapy.Request(link, callback=self.parse_product)

Эта функция парсит URL-адреса продуктов, и через цикл мы передаем их в другую функцию для парсинга информации о продукте.

Внутри нашей функции parse_product() мы парсим необходимую информацию и сохраняем ее в словаре

    def parse_product(self, response):
        data_dict = {}
        data_dict['Название продукта']=response.css("#page-heading>h1").get()
        data_dict['Артикул продавца']= response.css(".entry ul li:nth-child(8)::text").get().split(": ")[1]
        data_dict['Описание']=response.css(".entry ::text").getall()
        data_dict['URL изображения']=response.css(".slide>a::attr(href)").get()
        yield data_dict

Затем нам нужно инициализировать класс CrawlProcess и передать наш класс парсера в качестве аргумента.

process = CrawlerProcess()
process.crawl(beutlich_scraper)
process.start()

При запуске этого кода этот парсер будет парсить информацию и сохранять данные в формате csv.

Это конец блога.

Пожалуйста, поделитесь этим блогом со своими друзьями.

Пожалуйста, подпишитесь на меня в Twitter. https://twitter.com/faheem2920