Пагинация в Axios: как собирать данные с нескольких страниц
In this guide, I’ll show you how to use Axios, a popular tool for making HTTP requests in Node.js, to scrape paginated websites. But, Axios alone can’t handle pagination on its own. We’ll need to write some extra code to move from one page to the next until we’ve collected all the data.
По ходу дела мы также разберем, как обрабатывать пагинацию на JavaScript и не попасть под блокировку во время скрейпинга. Давайте погрузимся в тему и начнем!
Что такое пагинация?
Пагинация — это техника, которую сайты используют, чтобы разделять большие объемы данных на несколько страниц. Вместо загрузки всех данных сразу сайт показывает ограниченное число элементов на каждой странице, а пользователи могут переходить между ними с помощью кнопок или ссылок.
Существует три распространенных типа пагинации:
- Numbered Pagination — Страницы пронумерованы, например 1, 2, 3, 4, …
- Кнопки «Следующая» и «Предыдущая» — Пользователи нажимают Next, чтобы перейти вперед, или Previous, чтобы вернуться назад.
- Infinite Scrolling — Новые данные загружаются автоматически по мере прокрутки страницы вниз.
Каждый тип требует разного подхода к скрейпингу. Начнем с самого простого: пагинации с нумерацией страниц.
Настройка Axios для веб-скрейпинга
Чтобы собирать данные с пагинацией, нам понадобятся два npm-пакета:
- Axios — Популярный HTTP-клиент для отправки запросов к сайтам
- Cheerio — Легковесная библиотека для парсинга HTML и извлечения данных
Установите Axios и Cheerio
First, create a new Node.js project and install the required packages:
mkdir axios-pagination-scraper
cd axios-pagination-scraper npm init -y npm install axios cheerio
Теперь можно приступать к написанию нашего скрейпера.
Сбор данных с сайтов с нумерованной пагинацией
Шаг 1: Базовый скрейпер для одной страницы
Мы извлечем сведения о товарах (название, цену и URL изображения) с вымышленного интернет-магазина, который использует нумерованную пагинацию.
const axios = требуется('axios');
const cheerio = требуется('cheerio');
const url = 'https://www.scrapingcourse.com/ecommerce/?page=1';
async функция scrapePage(pageUrl) {
попробуйте {
const ответ = ожидайте axios.получить(pageUrl);
если (response.статус !== 200) {
консоль.ошибка(`Error: ${response.status}`);
возврат [];
}
const $ = cheerio.загрузка(response.data);
const products = [];
$('.product').each((index, productпрокси {
const name = $(product).find('.product-name').текст().отделка();
const price = $(product).find('.product-price').текст().отделка();
const imageUrl = $(product).find('.product-image').attr('src');
products.push({ Name: name, Price: цена, Image: imageUrl });
});
возврат products;
} поймать (ошибка) {
консоль.ошибка(`Error: ${error.message}`);
возврат [];
}
}
(async () => {
const products = ожидайте scrapePage(url);
консоль.журнал(products);
})();
Этот скрипт извлекает товары только с первой страницы. Теперь давайте изменим его, чтобы собирать данные с нескольких страниц.
Шаг 2: Скрейпинг нескольких страниц
Нам нужно обойти каждую страницу и извлечь данные, чтобы собрать информацию со всех страниц. Предположим, что на сайте 12 страниц.
async функция scrapeAllPages(baseURL, totalPages) {
пусть allProducts = [];
для (пусть i = 1; i <= totalPages; i++) {
const pageUrl = `${baseURL}?page=${i}`;
консоль.журнал(`Scraping: ${pageUrl}`);
const products = ожидайте scrapePage(pageUrl);
allProducts = […allProducts, …products];
}
возврат allProducts;
}
(async () => {
const allProducts = ожидайте scrapeAllPages('https://www.scrapingcourse.com/ecommerce/', 12);
консоль.журнал(allProducts);
})();
Эта версия собирает данные со всех 12 страниц и объединяет их в один массив.
Сбор данных с сайтов с кнопками «Next» и «Previous»
Некоторые сайты не используют пагинацию с нумерацией страниц, а вместо этого предоставляют кнопки «Следующая» и «Предыдущая».
Чтобы справиться с этим, нам нужно:
- Извлеките «Следующая страница» URL.
- Рекурсивно переходить на следующую страницу, пока не останется Next button.
Шаг 1: измените скрейпер, чтобы он определял ссылку на следующую страницу
async функция scrapePages(url) {
пусть products = [];
попробуйте {
const ответ = ожидайте axios.получить(url);
если (response.статус !== 200) {
консоль.ошибка(`Error: ${response.status}`);
возврат products;
}
const $ = cheerio.загрузка(response.data);
$('.product').each((index, productпрокси {
const name = $(product).find('.product-name').текст().отделка();
const price = $(product).find('.product-price').текст().отделка();
const imageUrl = $(product).find('.product-image').attr('src');
products.push({ Name: name, Price: цена, Image: imageUrl });
});
const nextPage = $('.next').attr('href');
если (nextPage) {
консоль.журнал(`Scraping next page: ${nextPage}`);
const nextProducts = ожидайте scrapePages(nextPage);
products = […products, …nextProducts];
}
} поймать (ошибка) {
консоль.ошибка(`Error: ${error.message}`);
}
возврат products;
}
(async () => {
const allProducts = ожидайте scrapePages('https://www.scrapingcourse.com/ecommerce/');
консоль.журнал(allProducts);
})();
Теперь скрейпер автоматически переходит по кнопке «Следующая», пока не закончатся страницы.
Handling JavaScript-Based Pagination
Сайты, использующие JavaScript для динамической загрузки данных, нельзя собрать только с помощью Axios. Нужен headless-браузер, например Puppeteer или Playwright.
Использование Puppeteer для бесконечной прокрутки
Install Puppeteer:
npm install puppeteer
Измените скрейпер:
const кукловод = требуется('puppeteer');
async функция scrapeInfiniteScroll(url) {
const браузер = ожидайте кукловод.запуск();
const страница = ожидайте браузер.newPage();
ожидайте страница.перейти по ссылке(url, { waitUntil: 'networkidle2' });
пусть products = [];
в то время как (true) {
const newProducts = ожидайте page.evaluate(() => {
возврат Массив.с сайта(документ.querySelectorAll('.product')).map(продукт => ({
Name: product.querySelector('.product-name').innerText,
Price: product.querySelector('.product-price').innerText,
Image: product.querySelector('.product-image').src
}));
});
products = […products, …newProducts];
const loadMore = ожидайте page.$('.load-more');
если (loadMore) {
ожидайте loadMore.click();
ожидайте страница.waitForTimeout(2000);
} else {
перерыв;
}
}
ожидайте браузер.закрыть();
возврат products;
}
(async () => {
const allProducts = ожидайте scrapeInfiniteScroll('https://www.scrapingcourse.com/infinite-scroll');
консоль.журнал(allProducts);
})();
Этот скрейпер прокручивает страницу и нажимает кнопку “Load More”, пока не перестанет появляться новый контент.
Avoiding Anti-Bot Detection
Сайты часто блокируют скрейперы с помощью CAPTCHA, IP-банов и JavaScript-челленджей. Чтобы этого избежать:
- Use прокси с ротацией
- Рандомизируйте заголовки запросов и строки User-Agent
- Добавляйте задержки между запросами
- С помощью надежного решения вроде Яркие данные или Oxylabsчто автоматически обходит антибот-защиту. Простой пример кода:
const axios = требуется('axios');
const url = 'https://www.scrapingcourse.com/antibot-challenge';
const apiKey = 'YOUR_Bright Data_API_KEY';
axios.получить(`https://api.brightdata.com/v1/?url=${url}&apikey=${apiKey}&js_render=true`)
.затем(ответ => консоль.журнал(response.data))
.поймать(ошибка => консоль.журнал(error));
Заключение
При сборе данных с нескольких страниц важно понимать антибот-механизмы, которые сайты часто используют. Хотя инструменты вроде Axios и Cheerio отлично подходят для обработки базовой пагинации, эти антибот-системы все равно могут мешать. Поэтому я рекомендую использовать Bright Data или Oxylabs. Это полноценное решение для веб-скрейпинга, которое помогает собирать данные с сайтов без риска блокировки.
С Bright Data или Oxylabs вы можете получить доступ к ротируемым прокси, решению CAPTCHA и другим инновационным функциям, которые делают скрейпинг проще и надежнее. Так что, если вы хотите, чтобы ваш скрейпинг проходил гладко и без перебоев, Bright Data и Oxylabs определенно стоит рассмотреть. Это сэкономит вам время и избавит от лишней головной боли, чтобы вы могли сосредоточиться на сборе нужных данных!

