Puppeteer — это мощный инструмент для тестирования, очистки и выполнения всевозможных удивительных вещей, которые вы обычно не можете делать в обычном сеансе просмотра из-за его доступа к низкоуровневому API Chrome. Вы должны следовать документации для установки puppeteer, прежде чем продолжить эту статью.

Ключевые идеи

  • Получить несколько элементов в Puppeteer
  • Перебор страниц в Puppeteer

Что такое кукольник?

Puppeteer — это библиотека автоматизации браузера для JavaScript, которая использует API браузера Chrome для доступа к низкоуровневым функциям браузера. Puppeteer — действительно полезный инструмент для веб-скрейпинга и тестирования, потому что вы можете автоматизировать взаимодействие с пользователем в браузере таким образом, который будет интуитивно понятен программистам (если вы поймете, как это работает).

Почему я использовал его?

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

Объяснение навигации по DOM в puppeteer

Навигация по DOM (объектная модель документа) в puppeteer использует селекторы CSS, поэтому для людей, знакомых с CSS, это упрощает доступ к нескольким элементам. Элементы, значения которых вы хотите получить, должны быть оценены, и я предполагаю, что это делается из соображений скорости, чтобы, когда кукловод перемещается по куполу, ему не нужно было вычислять значения каждого узла.

Инструменты

Мне нравится разбивать использование кода на управляемые инструменты, которые можно использовать в различных ситуациях, поскольку вы адаптируете код в конце статьи к своим собственным сценариям, поэтому я попытаюсь объяснить каждую часть кода.

браузер

Чтобы создать новый сеанс для браузера puppeteer, вы должны запустить новый экземпляр. Это запустит новый экземпляр хрома без головы (если не указано иное).

const browser = await puppeteer.launch();

страница

Чтобы создать шаблон страницы в новом экземпляре браузера, запустите приведенный ниже код из возвращенного объекта, вы можете запустить метод для доступа к вашему веб-сайту ().

const page = await browser.newPage();
await page.goto('www.example.com');

ждатьфортаймаут()

Страницы, которые загружаются в puppeteer, обычно требуют некоторого времени для загрузки, поэтому я использовал waitForTimeout, чтобы отложить запуск страницы на 1 секунду. Это дает веб-сайту время для загрузки контента, хотя это не рекомендуется кукловодом (альтернатива — waitForSelector).

await page.waitForTimeout("1000")

$$()

Этот метод работает с объектом страницы и любыми последующими узлами в DOM и может использоваться для выбора узлов в массив. Для меня, который получал список строк таблицы, я смог получить к ним доступ с помощью селектора CSS (см. код ниже).

const rows = await page.$$("tbody > tr")

$оценка()

Чтобы получить доступ к значениям, которые находятся внутри элемента, этот элемент необходимо оценить. Код ниже принимает элемент и возвращает любое текстовое содержимое.

await page.$eval("#searchgto_info", ele => ele.textContent)

$$оценка()

Делает то же самое, что и $eval, но возвращает массив элементов, к которым можно получить доступ.

получить свойство ()

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

await (await td.getProperty('innerHTML')).jsonValue()

щелчок()

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

await page.click("#nextPage")

Скриншот()

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

await page.screenshot({path: 'example.png'});

закрывать()

Наконец, браузер закрывается, как только мы закончим сеанс, и это уничтожит экземпляр chrome.

await browser.close();

Код

const puppeteer = require('puppeteer');
var fs = require('fs');
(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://www.example.com');
  await page.waitForTimeout("1000")
  let data = []
  do {
    const rows = await page.$$("tbody > tr")
    for (const row of rows) {
      let entry = []
      const dataItems = await row.$$("td")
      const tds = dataItems
      for (const key in tds) {
        if (Object.hasOwnProperty.call(tds, key)) {
          const td = tds[key];
          if (key !== "0") {
            try {
              entry.push(await td.$eval("a", ele => ele.textContent))
            } catch (error) {
              entry.push(await (await td.getProperty('innerHTML')).jsonValue())
            }
          }
          if(key === "0") {
            const allText = await td.evaluate(el => el.textContent)
            entry.push(allText)
          }
        }
      }
      pageData = entry
      data = [...data, entry]
    }
    await page.click("#searchgto_next")
    await page.screenshot({path: 'example.png'});
  } while (await page.$eval("#searchgto_info", ele => ele.textContent) != "Showing 767 to 807 of 207 entries");
  fs.writeFile("test.txt", JSON.stringify(data), function(err) {
    if (err) {
        console.log(err);
    }
});
  console.log("finito")
  await browser.close();
})();

Заключительные мысли

Puppeteer — отличный способ легко получить информацию с веб-страницы для тех, кто уже знаком с HTML и JavaScript. Методы, которые используются здесь, легко воспроизвести на другом веб-сайте. Если вы хотите узнать, как это сделать, но не можете придумать, как это сделать, вы можете просмотреть результаты поиска Google и посмотреть, сможете ли вы поместить информацию в CSV. В моем случае я вывел результаты в объект JSON, а затем импортировал результаты в Power BI, чтобы дать заголовки массива, но вы можете расширить мой сценарий и создать CSV в JavaScript, если хотите.