Nodul LogoNodul
Инструменты кода

Headless браузер

Headless браузер

Описание узла

Headless браузер — узел типа «действие», необходимый для настройки взаимодействия с веб-браузером с помощью JavaScript-кода.

Вы можете использовать нашего GPT-ассистента для помощи с Headless браузером:

👉 Nodul Headless Browser Assistant

Он поможет генерировать Puppeteer-код, работать с селекторами, отлаживать скрипты автоматизации браузера и решать типичные задачи с headless-браузером.

Базовый пример — Получение содержимого body веб-страницы

// Открываем веб-страницу и возвращаем содержимое элемента <body>
await page.goto('https://nodul.ru');
const bodyContent = await page.evaluate(() => document.body.innerHTML);
return { bodyContent };

Пример #2 — Ожидание HTML-элемента перед получением содержимого body

Некоторые веб-страницы загружают контент динамически с помощью JavaScript. В таких случаях нужно дождаться появления определённого селектора перед продолжением, используя "await page.waitForSelector", как показано в примере ниже

/* 
* Автоматизация headless-браузера с Puppeteer
* Документация: https://nodul.ru/help/headless_browser
* ИИ-ассистент для написания кода для Headless Browser: https://nodul.ru/help/headless_browser_assistant
*/

// Базовый пример: Открываем веб-страницу и возвращаем содержимое элемента <body>
await page.goto('https://nodul.ru');
await page.waitForSelector('#termly-consent-preferences');

// Ждём загрузки body и извлекаем его содержимое
const bodyContent = await page.evaluate(() => document.body.innerHTML);

return { 
    bodyContent 
};

Вы можете получить селектор здесь:

![Получение селектора](./ cleanshot_20241101_at_09.05.35.png)

Настройка узла

Для настройки узла Headless browser необходимо:

  • Создать код в окне Code в соответствии с требованиями взаимодействия с браузером;
  • При необходимости заполнить блок полей Proxy.

Proxy

Блок настройки с полями:

  • Enter proxy address — поле для ввода адреса прокси, через который нужно перенаправить запрос.
  • Enter login — поле для ввода учётных данных для использования прокси.
  • Enter password — поле для ввода учётных данных для использования прокси.

Эти поля заполняются, если доступ к требуемому сайту ограничен только локальной сетью.

Результат обработки данных

Выходом Headless Browser может быть строка, числовое значение, JSON-объект и т.д. Результат обработки данных узла Headless Browser доступен для настройки параметров других узлов.

Рекомендуется оборачивать данные в строковом формате кавычками для дальнейшей корректной обработки.

Код

Библиотеки

Для взаимодействия с браузером с помощью JavaScript используется библиотека Puppeteer.

В больших JavaScript-скриптах может потребоваться установить Puppeteer локально на компьютер (информация об установке). Для установки JavaScript-библиотек на компьютер необходимо настроить NodeJS и NPM.

Исходная функция run

Исходная функция узла Headless browser выглядит так:

async function run({execution_id, input, data, page}) {
    return {

    }
}

Параметр "page" — это результат вызова browser.newPage библиотеки Puppeteer и имеет соответствующий интерфейс. Все взаимодействия со страницей браузера выполняются с помощью этого параметра. Прямого доступа к библиотеке puppeteer или браузеру из этой функции нет.

Почти все операции с объектом page асинхронны. Для удобства исходная функция run объявлена с ключевым словом async, что позволяет писать код с использованием async/await для лучшей обработки асинхронных операций.

Использование функции callWebhook

В коде узла Headless Browser нет прямого доступа к библиотекам типа axios или fetch.

Для асинхронных API-вызовов можно использовать функцию callWebhook. Она основана на библиотеке axios, но с немного уменьшенной функциональностью.

С помощью этой функции можно делать API-запросы только к входящим узлам Trigger on Webhook, созданным на платформе Nodul. Запросы к другим доменам приведут к ошибке.

Интерфейс функции callWebhook(webhookUrl, options) аналогичен интерфейсу axios request и состоит из:

  • webhookUrl — URL входящего Trigger on Webhook на платформе Nodul;
  • options — объект с параметрами запроса.

Ответом будет объект с интерфейсом, аналогичным axios response.

Вот пример использования функции callWebhook:

async function run({execution_id, input, data, page}) {
  const response = await callWebhook("https://webhook.nodul.ru/137/dev/db76895b-093b-4a6e-a3a1-57edcaa36a5c", {
    method: "POST",
    data: {
        "some": "data"
    }
  });
  console.log(response.data);
  return {

  }
}

В результате в логах отобразится объект, возвращённый скриптом, который был вызван через функцию callWebhook для соответствующего Trigger on Webhook.

Примеры

Поисковый запрос в Google

async function run({execution_id, input, data, page}) {
  await page.goto('https://google.com');
// Ожидание появления поля ввода для поискового запроса
  await page.waitForXPath('/html/body/div[1]/div[3]/form/div[1]/div[1]/div[1]/div/div[2]/input');
  const searchInput =
      (await page.$x('/html/body/div[1]/div[3]/form/div[1]/div[1]/div[1]/div/div[2]/input'))[0];
// Ввод поискового запроса
  await searchInput.type('Hello world');

  const searchButton = (await page.$x('/html/body/div[1]/div[3]/form/div[1]/div[1]/div[4]/center/input[1]'))[0];
// Нажатие кнопки поиска
  await searchButton.click();
// Ожидание появления страницы результатов.
// Здесь можно использовать любой XPath к элементу,
// который надёжно появляется после успешного поиска
  await page.waitForXPath('//*[@id="result-stats"]');

// Выбор всех результатов
  const results = await page.$x('//*/a/h3[@class]');

  const responseArray = [];
// Построение итогового массива
  for (let result of results) {
      responseArray.push(await page.evaluate(el => ({ title: el.textContent }), result))
  }

// Возврат данных
  return {
      responseArray
  }
}

Пример сценария с использованием узла Headless Browser можно найти в документации [Настройка сценария](../ building_scenarios.mdx).

Возможные проблемы

UserAgent

Некоторые сайты могут не открываться через Headless Browser. В таких случаях следует использовать функцию page.setUserAgent.

await page.setUserAgent('Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36');

Не удаётся найти XPath

Headless Browser открывает браузер с помощью библиотеки puppeteer, которая, в свою очередь, открывает страницу с определённым viewport. Сайты могут иметь адаптивный дизайн, поэтому могут быть различия в вёрстке между локальным компьютером и Headless Browser. Вы можете изменить viewport страницы с помощью функции page.setViewport.

await page.setViewport({
  width: 1440,
  height: 900,
});