Puppeteer предоставляет мощные инструменты для автоматизации взаимодействия с веб-страницами, включая навигацию, клик, ввод текста и многое другое. Однако на практике в процессе работы с браузером могут возникать различные ошибки, особенно при навигации между страницами. Важно правильно обрабатывать такие ошибки, чтобы тесты не падали из-за нестабильности или непредвиденных ситуаций, таких как потеря соединения с сервером, медленная загрузка страницы или отсутствие элементов на странице.
При выполнении навигации через Puppeteer возможны несколько типов ошибок:
Эти ошибки могут привести к сбоям в тестах, что затрудняет их стабильность. Чтобы избежать таких проблем, важно реализовать обработку ошибок.
page.goto() и обработка ошибок
Метод page.goto() используется для перехода на указанную
страницу. Он имеет параметры, позволяющие настроить время ожидания и
политику обработки ошибок.
const puppeteer = require(&
async function navigateToPage() {
const browser = await puppeteer.launch();
const page = await browser.newPage();
try {
await page.goto('https://example.com', { waitUntil: 'load', timeout: 30000 });
console.log('Страница загружена');
} catch (error) {
console.error('Ошибка навигации:', error);
} finally {
await browser.close();
}
}
goto() для улучшенной обработки ошибок
Метод goto() позволяет настроить два ключевых параметра для
улучшенной обработки ошибок:
waitUntil — этот параметр позволяет задать
момент, когда считать страницу полностью загруженной. Можно использовать
следующие значения:
‘load’ — считается, что страница загружена, когда она
полностью загрузится.
‘domcontentloaded’ — загрузка будет считаться завершённой,
когда будет получен HTML-контент страницы.
‘networkidle0’ и ‘networkidle2’ — используются
для отслеживания состояния сети, когда запросы становятся неактивными.
timeout — указывает максимальное время в
миллисекундах для ожидания загрузки страницы. Если страница не
загрузилась в указанное время, будет выброшена ошибка.
try…catch
Для обработки ошибок при навигации рекомендуется использовать
конструкцию try…catch, которая позволяет перехватывать
исключения и принимать соответствующие меры.
const puppeteer = require('puppeteer');
async function navigateToPage() {
const browser = await puppeteer.launch();
const page = await browser.newPage();
try {
await page.goto('https://nonexistentpage.com', { timeout: 5000, waitUntil: 'load' });
console.log('Страница загружена');
} catch (error) {
console.error('Ошибка при переходе на страницу:', error.message);
} finally {
await browser.close();
}
}
При возникновении ошибки, такой как тайм-аут или недоступность страницы,
код в блоке catch будет выполнен, и ошибка будет выведена в
консоль.
После того как страница загрузилась, важно удостовериться, что
необходимые элементы действительно появились на ней. Для этого можно
использовать методы page.waitForSelector() или
page.waitForXPath(), которые позволяют подождать появления
элемента на странице. В случае, если элемент не появляется в пределах
заданного времени, выбрасывается ошибка.
const puppeteer = require('puppeteer');
async function navigateAndWaitForElement() {
const browser = await puppeteer.launch();
const page = await browser.newPage();
try {
await page.goto('https://example.com', { waitUntil: 'load', timeout: 30000 });
await page.waitForSelector('#main-content', { timeout: 10000 });
console.log('Элемент найден на странице');
} catch (error) {
console.error('Ошибка при ожидании элемента:', error);
} finally {
await browser.close();
}
}
В этом примере после загрузки страницы мы ожидаем появления элемента с
идентификатором #main-content. Если элемент не появляется в
течение 10 секунд, будет выброшена ошибка.
В некоторых случаях, например, при нестабильных интернет-соединениях или серверных проблемах, навигация может не удаваться с первой попытки. Чтобы минимизировать количество неудач, можно реализовать повторные попытки навигации.
const puppeteer = require('puppeteer');
async function navigateWithRetries(url, retries = 3) {
const browser = await puppeteer.launch();
const page = await browser.newPage();
for (let attempt = 1; attempt <= retries; attempt++) {
try {
await page.goto(url, { waitUntil: 'load', timeout: 30000 });
console.log(`Страница успешно загружена (попытка ${attempt})`);
break;
} catch (error) {
console.error(`Ошибка при переходе на страницу (попытка ${attempt}):`, error.message);
if (attempt === retries) {
console.error('Максимальное количество попыток исчерпано');
}
}
}
await browser.close();
}
Этот код реализует повторные попытки перехода на страницу в случае
неудачи. Количество попыток можно настроить через параметр
retries.
Если страницы загружаются слишком медленно, могут возникать ошибки времени ожидания. Для решения этой проблемы можно использовать следующие подходы:
timeout метода goto().
waitUntil с состоянием сети:
Если страница загружается в несколько этапов (например, сначала основной
HTML, затем изображения и другие ресурсы), можно использовать
waitUntil: ‘networkidle0’ или networkidle2 для
ожидания завершения всех сетевых запросов.
const puppeteer = require('puppeteer');
async function navigateWithLongTimeout() {
const browser = await puppeteer.launch();
const page = await browser.newPage();
try {
await page.goto('https://example.com', { waitUntil: 'networkidle0', timeout: 60000 });
console.log('Страница успешно загружена');
} catch (error) {
console.error('Ошибка при переходе на страницу:', error.message);
} finally {
await browser.close();
}
}
В данном примере используется настройка networkidle0, что
означает, что навигация завершится, когда сеть станет неактивной (когда
на странице не будет выполняться ни одного сетевого запроса).
Обработка ошибок при навигации в Puppeteer является неотъемлемой частью
написания стабильных и надежных тестов. Использование
try…catch, правильно настроенных параметров
goto(), таких как timeout и
waitUntil, а также применение методов ожидания элементов
поможет избежать большинства проблем. В случае нестабильных сетевых
условий или медленной загрузки страниц можно применить повторные попытки
или увеличить тайм-ауты, чтобы тесты оставались устойчивыми к временным
сбоям.