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

Как парсить Интернет с помощью Playwright в 2024 году

Playwright — это мощная библиотека автоматизации браузера, которая в 2024 году делает парсинг веб-страниц исключительно простым. Разработанная Microsoft и открытая в 2019 году, Playwright предоставляет первоклассный API для управления Chromium, Firefox и WebKit.

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

Из этого подробного руководства вы узнаете, как:

  • Создать проект драматурга
  • Запускайте браузеры и открывайте страницы
  • Взаимодействие с элементами на странице
  • Извлечение данных с веб-сайтов
  • Управление нумерацией страниц и сканирование между страницами
  • Управление ошибками и повторными попытками
  • Хранить очищенные данные
  • Развертывание парсеров Playwright в облаке

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

Начало работы с драматургом

Начнем с создания новой директории проекта и установки Playwright:

npm init -y
npm install playwright

Чтобы убедиться, что Playwright установлен правильно, создайте файл index.js и добавьте следующий код:

// index.js

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

(async () => {

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

  await page.goto(‘https://example.com‘);

  await browser.close();

})();

При этом запускается Chromium, открывается новая вкладка, осуществляется переход на сайт example.com, а затем браузер закрывается.

Запустите код с помощью:

node index.js

Вы должны увидеть открытую флэш-память Chromium и перейти на веб-сайт!

Запуск браузеров

Первое, что должен сделать любой сценарий драматурга, — это запустить экземпляр браузера, используя chromium.launch(), firefox.launch() or webkit.launch().

В параметрах запуска вы можете настроить такие параметры, как безгласный режим, пользовательский агент, геолокацию и многое другое:

const browser = await chromium.launch({
  headless: false,
  slowMo: 50 // Slow down Playwright by 50ms per action
});

Затем откройте страницы в браузере с помощью browser.newPage():

const page = await browser.newPage();

Обязательно закройте браузер по завершении:

await browser.close();

Чтобы заставить Драматурга открыть URL-адрес, используйте команду page.goto() Метод:

await page.goto(‘https://example.com‘);

Вы можете перемещаться вперед и назад по истории с помощью page.goBack() и page.goForward().

Взаимодействие с элементами страницы

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

Чтобы щелкнуть элемент с текстом «Зарегистрироваться», используйте:

await page.click(‘text="Sign up"‘); 

Это будет ждать, пока элемент не станет видимым, прежде чем щелкнуть.

Другие действия, такие как ввод текста, работают аналогично:

await page.fill(‘input[name="email"]‘, ‘[email protected]‘);

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

Playwright имеет первоклассную поддержку выбора элементов с помощью селекторов CSS и выражений XPath. Например:

const submit = await page.$(‘#submit‘);
await submit.click();

Это получает кнопку отправки по ее идентификатору, сохраняет ее в переменной и нажимает ее.

Извлечение данных

Чтобы извлечь текст или атрибуты из элементов, используйте команду element.textContent() и element.getAttribute() методы:

const title = await page.$(‘h1‘).textContent(); 

const src = await page.$(‘img‘).getAttribute(‘src‘);

Playwright также предоставляет мощные методы API, такие как page.textContent() и page.$$eval() для прямого извлечения данных:

// Get entire page text
const pageText = await page.textContent();

// Extract text from all .paragraph elements 
const paragraphs = await page.$$eval(‘.paragraph‘, elems => {
  return elems.map(elem => elem.textContent); 
});

В ожидании элементов

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

У драматурга есть полезные встроенные функции ожидания, такие как page.waitForSelector():

// Wait for #login to exist before clicking 
await page.waitForSelector(‘#login‘);
await page.click(‘#login‘);

Существуют также такие методы, как page.waitForTimeout() и page.waitForFunction() ждать произвольных условий.

// Wait 5 seconds
await page.waitForTimeout(5000);

// Wait for page title to contain "Dashboard"
await page.waitForFunction(
  () => document.title.includes(‘Dashboard‘)  
);

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

Обработка нумерации страниц

Многие веб-сайты имеют нумерацию страниц, при которой данные распределяются по нескольким страницам. Playwright упрощает автоматизацию нажатия кнопок «Далее» и извлечения данных со всех страниц.

Например:

let currentPage = 1;
let nextButton; 

do {

  // Extract data from current page
  // ...

  // Click next button if it exists
  nextButton = await page.$(‘text="Next"‘);
  if (nextButton) {
    await nextButton.click();
    currentPage++; 
  }

} while (nextButton); 

Это разбивается на страницы до тех пор, пока кнопка «Далее» больше не исчезнет. Та же логика работает для веб-сайта с бесконечной прокруткой: прокрутка вниз и ожидание загрузки дополнительных данных.

Управление ошибками и повторными попытками

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

Обернуть код в try/catch блоки для обработки конкретных ошибок:

try {
  await page.click(‘button‘); 
} catch (error) {
  // Handle error
}

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

const { Browser, BrowserContext, Page } = require(‘playwright‘);

const maxRetries = 5;
let retries = 0;

const browser = await Browser.launch();

while (retries <= maxRetries) {
  try {
    // Open page and scrape
    await doScrape(browser); 
    break; 
  } catch (error) {
    retries++;
    console.warn(`Retry #${retries}`);
  }
}

await browser.close();

async function doScrape(browser) {
  const context = await browser.newContext();
  const page = await context.newPage();

  // Scrape page ..

  await context.close(); 
}

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

Хранение очищенных данных

Чтобы сохранить очищенные данные, вы можете записать результаты в файл JSON:

const { writeFileSync } = require(‘fs‘);

// Scrape data...
const results = []; 

writeFileSync(‘data.json‘, JSON.stringify(results)); 

Для больших наборов данных вставьте их в базу данных, например MySQL, MongoDB или Elasticsearch. Апифай SDK предоставляет удобные средства экспорта данных для различных баз данных и служб облачного хранения.

Развертывание в облаке

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

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

Для развертывания в Apify вы объединяете свой сценарий драматурга в Апифи Актер Докер-контейнер. Этот контейнер можно запустить на платформе Apify через API или веб-интерфейс.

Платформа автоматически масштабирует параллелизм парсеров, управляет сбоями, устанавливает ограничения и сохраняет результаты. Нет серверов для управления!

Парсинг тем GitHub

Теперь давайте применим наши знания драматурга на практике, создав парсер для данных репозитория GitHub.

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

Мы будем использовать Темы GitHub страница в качестве нашей отправной точки.

Настройка проекта

Создайте новый каталог проекта:

mkdir github-scraper
cd github-scraper
npm init -y
npm install playwright

Запуск браузера

Сначала мы запустим экземпляр браузера Playwright Chromium и откроем новую страницу.

Создайте index.js:

// index.js

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

(async () => {

  const browser = await chromium.launch({ headless: false });
  const page = await browser.newPage();

  await page.goto(‘https://github.com/topics/javascript‘);

  await browser.close();

})(); 

Запустите это с node index.js и Chromium должен открыть страницу тем JavaScript.

Пагинация через репозитории

Изначально показано только 30 репозиториев. Нам нужно нажать кнопку «Загрузить больше» внизу страницы, чтобы увидеть больше.

Чтобы автоматизировать это, мы будем использовать page.click() и проверьте наличие кнопки с помощью page.$(selector):

// Click "Load more" button until it disappears
let loadMoreButton;
do {
  loadMoreButton = await page.$(‘text="Load more repositories"‘);
  if (loadMoreButton) {
    await loadMoreButton.click();
  }
} while (loadMoreButton);

Нам также нужно дождаться обновления страницы после нажатия. page.waitForSelector() хорошо работает здесь:

await page.waitForSelector(‘text="Load more repositories"‘); 

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

Извлечение данных репозитория

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

Сначала получить все .repo-list-item элементы:

const items = await page.$$(‘.repo-list-item‘);

Затем используйте element.textContent() и element.getAttribute() для извлечения значений текста и атрибутов из каждого:

const results = [];

for (const item of items) {
  const titleElement = await item.$(‘.repo-list-name a‘);
  const title = await titleElement.textContent();
  const url = await titleElement.getAttribute(‘href‘);

  const description = await item.$(‘.repo-list-description‘).textContent();

  // Get other data like stars count..

  results.push({
    title, 
    url,
    description
    // ... other properties 
  });
}

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

Повторная попытка при ошибках

GitHub иногда выходит из строя с ошибкой 429 «Слишком много запросов». Мы можем повторить попытку именно этой ошибки:

// Wrap in async function
const scrape = async () => {

  let retries = 0;

  while (retries < 3) {
    try {
      // Scrape page

      break; 
    } catch (error) {
      if (error.message.includes(‘429‘)) {
        retries++;
        console.log(‘Retrying...‘);
        continue;
      }
      throw error;
    }
  }

}

scrape();

Это повторяет до 3 раз код состояния 429, позволяя при этом всплывать другим ошибкам.

Вывод результата

В этом базовом примере мы выведем результаты на консоль:

console.table(results.slice(0, 10)); 

Полный код на данный момент доступен на GitHub.

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

Что дальше?

В этом руководстве рассмотрены основы парсинга веб-страниц с помощью Playwright, в том числе:

  • Запуск браузеров и навигация по страницам
  • Взаимодействие с элементами страницы
  • Извлечение данных
  • Ожидание загрузки
  • Пагинация данных
  • Управление ошибками и повторными попытками
  • Хранение результатов очистки

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

Чтобы глубже погрузиться в драматургию, посмотрите:

Удачного соскабливания!

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

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