CoderCastrov logo
CoderCastrov
JavaScript

Как обработать пагинацию с помощью Puppeteer: Практическое руководство по парсингу товаров на Amazon

Как обработать пагинацию с помощью Puppeteer: Практическое руководство по парсингу товаров на Amazon
просмотров
5 мин чтение
#JavaScript

Привет, друзья!

Если вы следите за моим блогом, то, возможно, помните наш последний эксперимент с парсингом веб-страниц с использованием Node.js и Puppeteer. В этой статье мы исследовали, как извлекать информацию из огромного каталога товаров на Amazon. Если вы еще не прочитали эту статью, рекомендую ознакомиться с ней здесь.

В духе последовательности, сегодня мы повысим наши навыки парсинга веб-страниц и решим новую задачу - обработку пагинации. Если вы когда-либо пытались извлечь данные с веб-сайта с несколькими страницами контента (например, результаты поиска на Amazon), то, возможно, чувствовали себя немного перегруженными. Но не волнуйтесь, потому что я здесь, чтобы поделиться тем, как я лично обрабатываю пагинацию при парсинге данных.


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


Настройка

Мы продолжим с того места, где остановились в прошлый раз. Если вы следовали предыдущему учебнику, у вас должен быть настроенный проект Node.js с установленным Puppeteer и базовым скриптом парсинга. Если нет, вам может потребоваться обратиться к предыдущей статье.

Как парсить товары на Amazon с помощью Node.js и Puppeteer

Привет! Вы когда-нибудь хотели извлечь данные из огромной базы товаров Amazon для исследования рынка, мониторинга цен...

blog.devgenius.io


Написание скрипта для пагинации

Если вы должны запомнить только одну вещь здесь, это:

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

Часто веб-сайты используют параметр запроса для отслеживания текущей страницы.

Например, на Amazon, если вы ищете "книги по JavaScript" и переходите на вторую страницу, вы увидите, что URL выглядит примерно так:

https://www.amazon.com/s?k=JavaScript+books&page=2

Вы можете видеть, как изменяется параметр запроса page, когда мы перемещаемся по страницам. Это наш билет для автоматизации процесса пагинации.

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

const products = [];

const handlePagination = async (page) => {
  products.push(...await extractProducts(page));
  try {
    await page.waitForSelector(
      ".s-pagination-next[aria-label]",
      {
        timeout: 4000,
      }
    );
    await page.click(".s-pagination-next[aria-label]");
    await page.waitForTimeout(4000);
    await handlePagination(page);
  } catch (err) {
    console.log("Больше нет страниц для загрузки");
  }
  return products;
};

В этой обновленной версии мы выделили извлечение продуктов в отдельную функцию extractProducts и добавили новую функцию handlePagination для управления навигацией по нескольким страницам. Эти изменения делают код более модульным и легким для поддержки.

Ваша функция scrapeProducts должна выглядеть так:

const scrapeProducts = async () => {
  try {
    const page = await initializePuppeteer();
    await page.goto("https://www.amazon.com/");
    await page.type("#twotabsearchtextbox", QUERY_TO_SEARCH);
    await page.click("#nav-search-submit-text");
    await page.waitForNavigation();

    const products = await handlePagination(page);
    console.log(products.length, "найдено продуктов");

    await closePuppeteer();
  } catch (err) {
    console.error(err);
    await closePuppeteer();
  }
};

Этот скрипт переходит по URL, парсит продукты на странице, а затем проверяет, существует ли ссылка на следующую страницу. Если да, URL следующей страницы добавляется в наш список URL для парсинга.

И вуаля! Вы только что обработали пагинацию с помощью Puppeteer.

Ваш файл scrape.js должен выглядеть так:

const puppeteer = require("puppeteer");

const QUERY_TO_SEARCH = process.argv[2] || "JavaScript book";
let browser;
const products = [];

/** * Запускает новый экземпляр Puppeteer и возвращает новый объект страницы. * @returns {Promise<Page>} Новый объект страницы. */
const initializePuppeteer = async () => {
  browser = await puppeteer.launch({ headless: false });
  return await browser.newPage();
};

/** * Закрывает экземпляр браузера, созданный Puppeteer. */
const closePuppeteer = async () => await browser.close();

/** * Извлекает информацию о продуктах из предоставленной страницы * @param {Page} page * @returns {Promise<Array<Object>>} Массив с информацией о продуктах */
const extractProducts = async (page) => {
  return page.evaluate(() => {
    let results = [];
    const items = document.querySelectorAll(".s-result-item .s-card-border");
    for (let i = items.length; i--; ) {
      const item = items[i];
      const title = item.querySelector("h2 > a > span");
      const price = item.querySelector(".a-price-whole");
      const cents = item.querySelector(".a-price-fraction");
      const image = item.querySelector("img");
      if (!title || !price || !image) continue;
      results = [
        ...results,
        {
          title: title.innerText,
          price: !cents?.innerText.length
            ? parseInt(price.innerText)
            : parseFloat(
                `${parseInt(price.innerText)}.${parseInt(cents.innerText)}`
              ),
          image: image.getAttribute("src"),
        },
      ];
    }
    return results;
  });
};

/** * Обрабатывает пагинацию, проверяет, есть ли следующая страница, если да, то рекурсивно обрабатывает следующую страницу. * @param {Page} page - Экземпляр страницы Puppeteer * @returns {Promise<Array<Object>>} - Массив всех продуктов со всех страниц */
const handlePagination = async (page) => {
  products.push(...await extractProducts(page));
  try {
    await page.waitForSelector(
      ".s-pagination-next[aria-label]",
      {
        timeout: 4000,
      }
    );
    await page.click(".s-pagination-next[aria-label]");
    await page.waitForTimeout(4000);
    await handlePagination(page);
  } catch (err) {
    console.log("Больше нет страниц для загрузки");
  }
  return products;
};

/** * Инициализирует Puppeteer, переходит на Amazon, выполняет поиск запроса, ожидает загрузки результатов, * затем парсит результаты и обрабатывает пагинацию */
const scrapeProducts = async () => {
  try {
    const page = await initializePuppeteer();
    await page.goto("https://www.amazon.com/");
    await page.type("#twotabsearchtextbox", QUERY_TO_SEARCH);
    await page.click("#nav-search-submit-text");
    await page.waitForNavigation();

    const products = await handlePagination(page);
    console.log(products.length, "найдено продуктов");

    await closePuppeteer();
  } catch (err) {
    console.error(err);
    await closePuppeteer();
  }
};

scrapeProducts();

Запуск и парсинг

Как всегда, выполните следующую команду, чтобы выполнить файл scrape.js:

node scrape.js

Вывод должен быть сообщением с количеством найденных продуктов:

Найдено 383 продукта

Заключение

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

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

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

Как всегда, помните о этическом парсинге. Счастливого кодирования и до встречи в следующий раз!



[Раскрытие информации: Каждая статья, которую я пишу, является слиянием моих идей и поддерживающих возможностей искусственного интеллекта. В то время как ИИ помогает уточнять и разрабатывать, основные мысли и концепции исходят из моей перспективы и знаний. Чтобы узнать больше о моем творческом процессе, прочитайте эту статью.]

Как искусственный интеллект помогает мне писать мои статьи?

Ландшафт Medium претерпел трансформацию, с появлением все большего количества статей, имеющих отчетливую...

medium.com