перейти к содержанию

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

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

Однако растущая зависимость от клиентского JavaScript и асинхронной загрузки данных создает уникальные проблемы для извлечения данных из одностраничных приложений. Традиционные инструменты парсинга не оправдывают ожиданий, поскольку они предназначены для статических сайтов и анализа HTML.

В этом подробном руководстве, состоящем из более чем 3200 слов, вы изучите проверенные методы решения распространенных препятствий, с которыми сталкиваются при очистке современных SPA с помощью Playwright.

Почему парсинг SPA является сложной задачей

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

Интенсивное использование клиентского JavaScript

HTML-код, изначально обслуживаемый сервером, по сути, является статической оболочкой страницы. Фактический контент динамически генерируется и отображается на стороне клиента с помощью JavaScript. Это означает, что большая часть данных существует только в объектах JavaScript и элементах DOM, а не в исходном источнике HTML.

Асинхронная загрузка данных

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

Согласно метрикам Radware, средняя веб-страница при рендеринге делает более 100 запросов к внешним ресурсам.

ГодСреднее количество запросов страниц
201133
201656
2019105

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

Динамическое манипулирование DOM

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

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

Зависимость от API и запросов AJAX

SPA широко используют REST API, GraphQL, WebSockets и запросы AJAX для получения данных с внутренних серверов. Затем контент отображается на стороне клиента.

Этот обмен данными между клиентом и сервером невидим для традиционных подходов к парсингу, которые видят только первоначальный ответ HTML.

Аутентифицированные сеансы и состояние

Сложные SPA часто требуют от пользователей входа в систему перед доступом к личному контенту и данным. Это состояние аутентификации необходимо правильно поддерживать в сценариях очистки.

Файлы cookie, хранящие идентификаторы сеансов, идентификаторы пользователей и токены, должны обрабатываться так, чтобы имитировать сеанс аутентифицированного пользователя.

Необходимость выполнения JavaScript

В отличие от статических сайтов, для SPA недостаточно простого анализа HTML. Страница должна быть отображена путем выполнения JavaScript в среде, похожей на браузер, для создания окончательной структуры данных.

Безголовые браузеры, такие как Playwright, предоставляют эту возможность для создания реалистичного взаимодействия с конечным пользователем, необходимого для очистки SPA.

Эти проблемы делают эффективный парсинг SPA совершенно отличным от обычного парсинга веб-страниц. Давайте теперь посмотрим, как «Драматург» может помочь вам преодолеть эти препятствия.

Зачем использовать Playwright для очистки SPA?

Playwright — это библиотека Node.js для автоматизации популярных веб-браузеров, таких как Chromium, Firefox и WebKit. Ключевые возможности, необходимые для парсинга SPA, включают:

Безголовая автоматизация браузера

Playwright может управлять браузерами без отображения видимого пользовательского интерфейса, известного как безголовый режим. Это позволяет выполнять тяжелые страницы JavaScript для заполнения данных.

Ожидание элементов и условий

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

Имитирующие запросы API

Playwright позволяет перехватывать запросы и отвечать с помощью фиктивных данных вместо вызова реальных API. Это позволяет очищать данные AJAX.

Отзывчивое тестирование

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

Средство просмотра трассировки

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

Автоматическая обработка всплывающих окон и диалогов

Playwright автоматически обрабатывает оповещения, подтверждения, подсказки, запросы аутентификации и загрузки, упрощая логику сценария.

Селекторы и DOM API

Богатый API для извлечения данных с помощью селекторов CSS или прямого перемещения по элементам DOM, как на обычной веб-странице.

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

Далее давайте рассмотрим несколько примеров кода, демонстрирующих шаблоны очистки ключей с помощью Playwright.

Создание шаблонов для SPA с помощью Playwright

Ниже мы рассмотрим некоторые распространенные методы очистки для решения конкретных проблем SPA.

Подождите, пока контент загрузится

Одной из наиболее фундаментальных проблем парсинга SPA является предоставление времени для загрузки контента перед извлечением.

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

Драматургический page.waitForSelector() Метод позволяет дождаться появления определенного селектора перед выполнением дальнейших команд:

// Navigate to SPA
await page.goto(‘https://spa.com‘);

// Wait for content to load
await page.waitForSelector(‘.content‘);

// Extract data now that .content exists
const data = await page.$eval(‘.content‘, elem => elem.textContent); 

Это ждет, пока элемент с классом content доступен в DOM до извлечения его текстового содержимого.

Без этого ожидания, .content может еще не существовать, если все еще загружается асинхронно, вызывая ошибки. Эта простая задержка дает SPA время на выборку и обработку новых данных, позволяющих их последующее извлечение.

WaitForFunction

В некоторых случаях нам может потребоваться дождаться, пока истинными станут более сложные условия JavaScript, а не простой селектор. Здесь мы можем использовать page.waitForFunction():

// Wait for data to load
await page.waitForFunction(() => {
  return window.store.articles.length > 0 ;
});

// Store now has loaded articles
const articles = await page.evaluate(() => {
  return window.store.articles; 
});

Это опрашивает страницу до тех пор, пока пользователь window.store.articles условие возвращает true перед чтением данных.

Интеллектуальное ожидание селекторов и условий предотвращает сбои очистки из-за асинхронной загрузки данных страницы.

Обработка обновлений динамического контента

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

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

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

// Monitor mutations
await page.evaluate(() => {

  const observer = new MutationObserver(mutations => {
    console.log(‘Added nodes:‘, mutations[0].addedNodes);
  });

  observer.observe(document, { 
    childList: true,
    subtree: true
  });

});

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

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

Ложные запросы API

SPA широко используют API-интерфейсы REST и GraphQL для получения данных на стороне клиента.

Чтобы перехватить эти запросы, мы можем определить в Playwright маршруты для имитации ответов:

await page.route(‘/api/articles‘, route => {
  route.fulfill({
    status: 200,
    body: JSON.stringify([
      {title: ‘Article 1‘},
      {title: ‘Article 2‘}  
    ])
  }); 
});

// Mock response will be returned from /api/articles
await page.goto(‘/page-that-calls-api‘) 

Когда SPA пытается позвонить /api/articles, наш обработчик ответит определенным ложным ответом вместо обращения к реальному API.

Это позволяет очищать данные API без побочных эффектов. Мы можем создавать надежные ответы для обработки различных сценариев, которые может ожидать наш код SPA.

Аутентификация сеанса

Для очистки личных учетных записей в SPA требуется правильная аутентификация.

Простой подход — обычно войти в систему через пользовательский интерфейс перед очисткой:

// Navigate to login page
await page.goto(‘/login‘);

// Enter credentials and submit form 
await page.type(‘#email‘, ‘[email protected]‘);
await page.type(‘#password‘, ‘secret‘);
await page.click(‘#submit‘);

// Session now authenticated
// Crawl member pages 

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

Для достижения наилучших результатов выполните вход в систему beforeAll перехватить и повторно использовать browser и page контекст во время тестов для обмена файлами cookie.

Адаптивный дизайн

SPA часто адаптируют свой макет и контент для устройств разных размеров. Чтобы протестировать эти адаптивные сценарии, мы можем эмулировать мобильные браузеры, используя page.emulate():

await page.emulate({
  viewport: {
    width: 400,  
    height: 800
  },
  userAgent: ‘...‘,
});

Настройка области просмотра iPhone и пользовательского агента позволяет отображать страницу так, как это делает мобильное устройство.

Объедините эмуляцию с waitForSelector и вы сможете надежно работать с адаптивным дизайном.

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

Вспомогательные библиотеки скрапера

Услуги, подобные апифай и Соскоб предоставить библиотеки на основе Playwright, которые интеллектуально обрабатывают ожидание контента, автоматизируют прокрутку при динамических обновлениях страниц, регулируют запросы и многое другое.

Эти инструменты могут упростить самостоятельное написание надежных сценариев очистки SPA.

Практический сценарий драматурга

Давайте теперь объединим эти подходы в реальный парсер для гипотетического SPA:

const { chromium } = require(‘playwright‘);

(async () => {

  const browser = await chromium.launch();
  const page = await browser.newPage();  

  // Login to scrape private content
  await page.goto(‘/login‘);
  await page.type(‘#email‘, ‘[email protected]‘);
  await page.type(‘#password‘, ‘secret‘); 
  await page.click(‘#submit‘);

  await page.waitForNavigation();

  // Navigate to SPA
  await page.goto(‘/app‘);

  // Wait for content to load
  await page.waitForSelector(‘.content‘);

  // Monitor mutations
  page.evaluate(() => {
    new MutationObserver().observe(document, {
      childList: true 
    });    
  });

  // Mock API response
  page.route(‘/api/articles‘, route => {
    route.fulfill({ /*...mock response...*/ }); 
  });

  // Extract content 
  const data = await page.evaluate(() => {
    const content = document.querySelector(‘.content‘);
    return content.innerText;
  });

  console.log(data);

  await browser.close();

})();

Этот скрипт входит в частное приложение, ожидает загрузки аутентифицированного контента, обрабатывает динамические мутации, имитирует ответ API и извлекает данные в const data.

Эти методы можно адаптировать для разработки надежных скребков для реальных СПА.

Очистка SPA в больших масштабах

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

Парсинг API-сервисов

API-интерфейсы веб-скрапинга, такие как СкребокAPI обрабатывать автоматизацию браузера, файлы cookie, прокси и ротацию в любом масштабе. Это упрощает очистку сайтов с интенсивным использованием JavaScript, включая SPA.

Безголовые браузерные фермы

Услуги, подобные Без браузера и Облачный браузер Sangfor предоставлять большие кластеры экземпляров Playwright и Puppeteer, доступных через API. Эти параллельные экземпляры позволяют выполнять распределенную очистку SPA в любом масштабе.

Размещенные краулеры

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

Веб-боты для парсинга

Такие инструменты, как Фантомбастер, Декси.ио и ParseHub обеспечить настройку парсеров для SPA в режиме «укажи и щелкни» без программирования. Эти боты автоматически определяют содержимое страницы, ожидания, клики и т. д., что позволяет выполнять настройку без кода.

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

Более простая альтернатива: Кроули

Кроули предоставляет инновационный веб-сканер в качестве услуги для сайтов, отображаемых на JavaScript.

Он автоматически решает распространенные проблемы парсинга, такие как:

  • Ожидание загрузки элементов или URL-адресов перед извлечением
  • Аутентификация сеансов и хранение файлов cookie
  • Перехват запросов API и обработка данных AJAX
  • Прокрутка страниц с бесконечной прокруткой
  • Повторный запуск неудачного извлечения для повышения устойчивости

Crawlee может «из коробки» просматривать сложные SPA без необходимости писать сценарии Playwright для ожидания, аутентификации, обработки AJAX и т. д.

Ключевые возможности:

  • Настройка через визуальный интерфейс вместо написания кода
  • Автоматическое ожидание URL-адресов и селекторов перед извлечением данных
  • Сканирование с отслеживанием состояния переносит файлы cookie на разные страницы.
  • Перехват API-запросов для обработки данных XHR, Fetch и JSON.
  • Безголовый рендеринг Chrome по умолчанию
  • Визуальные инструменты для проверки и отладки сканирования
  • Горизонтально масштабируемая распределенная серверная часть сканера

Это упрощает очистку даже сложных веб-приложений JavaScript без написания кода Playwright. Сканер Crawlee как услуга идеально подходит для пользователей, не желающих управлять собственной инфраструктурой парсеров.

Поддерживаемые приложения включают:

  • Приложения React и Next.js
  • Угловые SPA
  • Страницы Vue.js
  • Веб-сайты
  • Тяжелые страницы AJAX
  • PWA и приложения Electron
  • Динамичный и адаптивный дизайн

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

Заключение

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

Ключевые стратегии, описанные в этом руководстве, включают:

  • Ожидание загрузки исходного содержимого и динамических обновлений перед извлечением.
  • Прослушивание изменений DOM для обнаружения нового отображаемого контента.
  • Перехват запросов REST API и GraphQL для доступа к серверным данным
  • Эмуляция мобильных устройств и регулирование для адаптивного дизайна.
  • Аутентификация сеансов и управление файлами cookie для доступа к личным данным пользователя.

Следование этим шаблонам поможет вам разработать удобные в обслуживании парсеры Playwright даже для сложных SPA, в значительной степени полагающихся на клиентский JavaScript и API.

В масштабе использование парсинговых API-сервисов, автономных ферм браузеров и размещенных сканеров может быть более эффективным, чем создание собственной инфраструктуры Playwright.

Хотя написание сценариев Playwright обеспечивает максимальную гибкость, такие инструменты, как Crawlee, предоставляют более простой и готовый сервис очистки для SPA без необходимости самостоятельно писать сценарии автоматизации браузера.

Я надеюсь, что это руководство дало вам четкое представление о методах парсинга сложных одностраничных приложений с помощью Playwright. Дайте мне знать, если у вас есть еще вопросы!

Присоединяйтесь к беседе

Ваш электронный адрес не будет опубликован. Обязательные поля помечены * *