Работа с реальными данными
Ребята, конечно, здорово, что мы можем извлекать элементы
<title>
с веб-страниц, но это не очень полезно. Можем ли мы наконец собрать реальные данные и сохранить их в машиночитаемом формате? Ведь именно для этого я начал читать это руководство!
Мы слышим тебя, юный падаван! Сначала нужно научиться ползать, и только потом ходить по данным!
Создание промышленного краулера
Создать промышленный краулер несложно, но при скрапинге есть много подводных камней, которые могут застать вас врасплох. Поэтому для реального проекта вы научитесь скрапить демонстрационный магазин Warehouse вместо сайта Crawlee. Он содержит список товаров разных категорий, и у каждого товара есть своя страница с подробным описанием.
Сайт требует рендеринга JavaScript, что позволяет нам продемонстрировать больше возможностей Crawlee. Мы также добавили несколько полезных советов, которые подготовят вас к реальным проблемам, с которыми вы обязательно столкнетесь при масштабном скрапинге.
Если вас не интересует теория краулинга, можете перейти к следующей главе и сразу приступить к программированию.
Составление плана
Иногда скрапинг действительно прост, но в большинстве случаев полезно сначала провести небольшое исследование и попытаться ответить на следующие вопросы:
- Как структурирован сайт?
- Могу ли я скрапить его только с помощью HTTP-запросов (читай "с помощью
CheerioCrawler
")? - Нужен ли мне headless браузер для чего-либо?
- Есть ли на сайте защита от скрапинга?
- Нужно ли мне парсить HTML или я могу получить данные другим способом, например, напрямую через API сайта?
Для целей этого руководства предположим, что сайт нельзя скрапить с помощью CheerioCrawler
. На самом деле можно, но нам пришлось бы углубиться больше, чем позволяет это вводное руководство. Поэтому пока мы упростим задачу, будем скрапить с помощью PlaywrightCrawler
, и вы узнаете о headless браузерах в процессе.
Выбор нужных данных
Хороший первый шаг - определить, какие данные вы хотите собрать и где их найти. Пока давайте договоримся, что мы хотим собрать все товары из всех категорий, доступных на странице "Все коллекции" магазина, и для каждого товара мы хотим получить:
- URL
- Производитель
- Артикул
- Название
- Текущая цена
- Наличие на складе
Вы заметите, что некоторая информация доступна прямо на странице списка, но для получения таких деталей, как "Артикул", нам также нужно будет открыть страницу с подробным описанием товара.
Начальный URL(ы)
Это точка старта вашего краулинга. Удобно начинать как можно ближе к данным. Например, не имеет смысла начинать с https://warehouse-theme-metal.myshopify.com/
и искать там ссылку на collections
, когда мы уже знаем, что все, что мы хотим извлечь, можно найти на странице https://warehouse-theme-metal.myshopify.com/collections
.
Исследование страницы
Давайте внимательнее рассмотрим страницу https://warehouse-theme-metal.myshopify.com/collections
. На странице есть категории, и в каждой категории есть список товаров. На некоторых страницах категорий внизу вы заметите ссылки на следующие страницы результатов. Это обычно называется пагинацией.
Категории и сортировка
Когда вы нажимаете на категории, вы увидите, что они загружают страницу товаров, отфильтрованных по этой категории. Просмотрев несколько категорий и наблюдая за поведением, мы также можем заметить, что мы можем сортировать по разным условиям (например, Бестселлеры
или Цена, по возрастанию
), но для этого примера мы не будем рассматривать их.
Будьте осторожны, потому что на некоторых сайтах, например amazon.com, это не так, и сумма товаров в категориях фактически больше, чем доступно без фильтров. Узнайте больше в нашем руководстве по скрапингу сайтов с ограниченной пагинацией.
Пагинация
Пагинация в демонстрационном магазине Warehouse достаточно проста. При переключении между страницами вы увидите, что URL меняется на:
https://warehouse-theme-metal.myshopify.com/collections/headphones?page=2
Попробуйте перейти по ссылке на страницу 4. Вы увидите, что ссылки пагинации обновляются и показывают больше страниц. Но можете ли вы быть уверены, что это включит все страницы и не остановится в какой-то момент?
Аналогично проблеме с фильтрами, описанной выше, наличие пагинации не гарантирует, что вы можете просто пролистать все результаты. Всегда проверяйте свои предположения о пагинации. В противном случае вы можете пропустить часть результатов и даже не знать об этом.
На момент написания счетчик результатов коллекции Наушники
показывал 75 результатов - товаров. Быстрый подсчет товаров на одной странице результатов дает 24. 6 рядов по 4 товара. Это означает, что есть 4 страницы результатов.
Если вы не убеждены, вы можете посетить страницу где-то в середине, например https://warehouse-theme-metal.myshopify.com/collections/headphones?page=2
, и посмотреть, как там выглядит пагинация.
Стратегия краулинга
Теперь, когда вы знаете, с чего начать и как найти все детали актора, давайте рассмотрим процесс краулинга.
- Посетить страницу магазина, содержащую список категорий (наш начальный URL).
- Поставить в очередь все ссылки на все категории.
- Поставить в очередь все страницы товаров с текущей страницы.
- Поставить в очередь ссылки на следующие страницы результатов.
- Открыть следующую страницу в очереди.
- Если это страница списка результатов, перейти к пункту 2.
- Если это страница товара, собрать данные.
- Повторять, пока не будут обработаны все страницы результатов и все товары.
PlaywrightCrawler
позаботится о посещении страниц за вас, если вы предоставите правильные запросы, и вы уже знаете, как ставить страницы в очередь, так что это должно быть довольно просто. Тем не менее, есть еще несколько приемов, которые мы хотели бы продемонстрировать.
Проверка работоспособности
Давайте проверим, что все настроено правильно, прежде чем писать саму логику скрапинга. Вы можете обнаружить, что что-то в вашем предыдущем анализе не совсем сходится, или сайт может вести себя не совсем так, как вы ожидали.
Пример ниже создает новый краулер, который посещает начальный URL и выводит текстовое содержимое всех категорий на этой странице. Когда вы запустите код, вы увидите очень плохо отформатированное содержимое отдельной карточки категории.
- Playwright
- Playwright with Cheerio
// Вместо CheerioCrawler давайте использовать Playwright
// чтобы иметь возможность рендерить JavaScript.
import { PlaywrightCrawler } from 'crawlee';
const crawler = new PlaywrightCrawler({
requestHandler: async ({ page }) => {
// Дождитесь, пока карточки актеров будут рендериться.
await page.waitForSelector('.collection-block-item');
// Выполните функцию в браузере, которая нацеливается
// на элементы карточек актеров и позволяет их манипулировать.
const categoryTexts = await page.$$eval('.collection-block-item', (els) => {
// Извлеките текстовое содержимое из карточек актеров
return els.map((el) => el.textContent);
});
categoryTexts.forEach((text, i) => {
console.log(`CATEGORY_${i + 1}: ${text}\n`);
});
},
});
await crawler.run(['https://warehouse-theme-metal.myshopify.com/collections']);
// Вместо CheerioCrawler давайте использовать Playwright
// чтобы иметь возможность рендерить JavaScript.
import { PlaywrightCrawler } from 'crawlee';
const crawler = new PlaywrightCrawler({
requestHandler: async ({ page, parseWithCheerio }) => {
// Дождитесь, пока карточки актеров будут рендериться.
await page.waitForSelector('.collection-block-item');
// Извлеките HTML-код страницы из браузера
// и проанализируйте его с помощью Cheerio.
const $ = await parseWithCheerio();
// Используйте привычный синтаксис Cheerio для
// выбора всех карточек актеров.
$('.collection-block-item').each((i, el) => {
const text = $(el).text();
console.log(`CATEGORY_${i + 1}: ${text}\n`);
});
},
});
await crawler.run(['https://warehouse-theme-metal.myshopify.com/collections']);
Если вы задаетесь вопросом, как получить этот селектор .collection-block-item
. Мы объясним это в следующей главе о DevTools.
DevTools - инструментарий скрапера
Мы будем использовать Chrome DevTools, поскольку это самый распространенный браузер, но вы можете использовать любой другой, они все очень похожи.
Давайте откроем DevTools, перейдя на https://warehouse-theme-metal.myshopify.com/collections в Chrome, затем щелкнув правой кнопкой мыши в любом месте страницы и выбрав Просмотреть код или нажав F12 или то, что предпочитает ваша система. С помощью DevTools вы можете проверять или манипулировать любым аспектом текущей веб-страницы. Вы можете узнать больше о DevTools в их официальной документации.
Выбор элементов
В DevTools выберите инструмент Выбрать элемент и попробуйте навести курсор на одну из карточек актора.
Вы увидите, что можете выбирать разные элементы внутри карточки. Вместо этого выберите всю карточку, а не только ее содержимое, такое как заголовок или описание.
Выбор элемента подсветит его в инспекторе HTML DevTools. Внимательно рассмотрев элементы, вы увидите, что к разным HTML-элементам прикреплены некоторые классы. Они называются CSS-классами, и мы можем использовать их при скрапинге.
И наоборот, при наведении курсора на элементы в инспекторе HTML вы увидите, как они подсвечиваются на странице. Изучите структуру страницы вокруг карточки коллекции. Вы увидите, что все данные карточки отображаются в элементе <a>
с атрибутом class
, который включает collection-block-item. Теперь должно быть понятно, как мы получили этот селектор .collection-block-item
. Это просто способ найти все элементы, помеченные как collection-block-item
.
Всегда полезно проверить, что вы не получаете никаких нежелательных элементов с этим классом. Для этого перейдите на вкладку Консоль DevTools и выполните:
document.querySelectorAll('.collection-block-item');
Вы увидите, что будут возвращены только 31 карточка коллекции и ничего больше.
CSS-селекторы и DevTools - довольно большая тема. Если вы хотите узнать больше, посетите курс по веб-скрапингу для начинающих в Apify Academy. Он бесплатный и с открытым исходным кодом ❤️.
Следующие шаги
Далее вы будете краулить весь магазин, включая все страницы списков и все страницы с подробным описанием товаров.