В этом руководстве вы узнаете:
- Что такое Scrapy
- Что такое драматургия
- Функции, которые они предлагают для веб-скреппинга, и их сравнение
- Введение в веб-скраппинг с помощью обоих инструментов
- Как создать скребок с помощью Playwright
- Как создать скрипт для веб-скреппинга с помощью Scrapy
- Какой инструмент лучше для веб-скреппинга
- Их общие ограничения и способы их преодоления
Давайте погрузимся!
Что такое Scrapy?
Scrapy – это фреймворк для веб-скрапинга с открытым исходным кодом, написанный на Python и предназначенный для эффективного извлечения данных. Он предлагает встроенную поддержку таких возможностей, как параллельные запросы, переход по ссылкам и экспорт данных в форматы JSON и CSV. Кроме того, в нем есть промежуточное ПО, интеграция с прокси и автоматические повторы запросов. Scrapy работает асинхронно и на статических HTML-страницах.
Что такое драматург?
Playwright – это фреймворк с открытым исходным кодом для автоматизации E2E-тестирования и веб-скрапинга в браузере. Он поддерживает множество браузеров, таких как Chrome, Firefox и WebKit – как в режиме head, так и в режиме headless. Кроме того, API автоматизации браузера доступен на нескольких языках программирования, включая TypeScript/JavaScript, Python, Java и C#.
Scrapy против Playwright: основные возможности веб-скрапинга
Давайте сравним Scrapy и Playwright по пяти различным аспектам, которые делают их отличными инструментами для веб-скрапинга.
О других статьях в блоге, посвященных противостоянию, читайте:
- Scrapy против Beautiful Soup
- Scrapy против Pyspider: Что лучше для веб-скрапинга?
- Scrapy против Selenium для веб-скрапинга
- Scrapy против Puppeteer для веб-скрапинга
- Scrapy против Requests: Что лучше для веб-скрапинга?
Итак, начинаем сравнение Scrapy и Playwright!
Простота установки и конфигурирования
Scrapy предлагает простую настройку с минимальными требованиями к конфигурации. Вы можете быстро создать проект, определить пауков и экспортировать данные благодаря встроенному CLI. Напротив, Playwright требует более тщательной настройки, поскольку включает установку зависимостей браузера и проверку правильности конфигурации.
Кривая обучения
Scrapy имеет более сложную кривую обучения для новичков из-за своей модульной структуры, широких возможностей и уникальных конфигураций. Понимание таких понятий, как пауки, промежуточные модули и конвейеры, может занять некоторое время. С Playwright гораздо проще начать работу, поскольку его API знаком тем, кто имеет некоторые знания об автоматизации браузеров.
Работа с динамическим содержимым
Scrapy испытывает трудности с веб-сайтами, использующими JavaScript, поскольку может работать только со статичными HTML-документами. Работа с динамическим контентом возможна, но требует интеграции с Splash или аналогичными инструментами. Playwright отлично справляется с динамическим или JavaScript-рендерингом, так как он изначально рендерит страницы в браузере. Это означает, что вы можете использовать его для соскабливания страниц, которые опираются на клиентские фреймворки, такие как React, Angular или Vue.
Настройка и расширяемость
Scrapy предлагает широкие возможности настройки благодаря поддержке промежуточных модулей, расширений и конвейеров. Кроме того, доступно несколько плагинов и дополнений. Playwright, с другой стороны, не имеет встроенных расширений. К счастью, сообщество решило эту проблему с помощью проекта Playwright Extra.
Другие возможности скрапинга
Scrapy оснащен такими встроенными функциями, как интеграция с прокси, автоматические повторные попытки и настраиваемый экспорт данных. Она также предлагает встроенные методы для ротации IP-адресов и другие продвинутые сценарии. Playwright не поддерживает интеграцию с прокси и другие ключевые функции скрапинга. Поэтому для достижения тех же результатов требуется больше ручных усилий по сравнению со Scrapy.
Playwright vs Scrapy: Сравнение скриптов для скрапинга
В следующих двух разделах вы узнаете, как соскрести один и тот же сайт с помощью Playwright и Scrapy. Мы начнем с Playwright, так как это может занять немного больше времени, поскольку он не оптимизирован для веб-скрапинга, как Scrapy.
Целевым сайтом будет песочница Books to Scrape для скрапинга:
Цель обоих скреперов – получить все книги Fantasy с сайта, что требует обработки пагинации.
Scrapy будет рассматривать страницы как статические и разбирать их HTML-документы напрямую. Вместо этого Playwright будет рендерить их в браузере и взаимодействовать с элементами на страницах, имитируя действия пользователя.
Скрипт Scrapy будет написан на Python, а скрипт Playwright – на JavaScript. Эти два языка в основном поддерживаются обоими инструментами. Тем не менее, вы можете легко преобразовать сценарий Playwright на JavaScript в Python с помощью библиотеки playwright-python
, которая предоставляет тот же базовый API.
В обоих случаях в конце сценария у вас будет CSV, содержащий все данные о книге Fantasy из Books to Scrape.
А теперь давайте перейдем к сравнению Playwright и Scrapy!
Как использовать Playwright для веб-скрапинга
Выполните следующие шаги, чтобы написать простой сценарий веб-скреппинга на JavaScript с помощью Playwright. Если вы не знакомы с этим процессом, прочитайте сначала наше руководство по веб-скреппингу с помощью Playwright.
Шаг №1: Настройка проекта
Прежде чем приступить к работе, убедитесь, что у вас локально установлена последняя версия Node.js. Если нет, загрузите ее и следуйте указаниям мастера установки.
Затем создайте папку для скребка Playwright и перейдите в нее с помощью терминала:
mkdir playwright-scraper
cd playwright-scraper
В папке playwright-scraper инициализируйте проект npm, выполнив команду:
npm init -y
Теперь откройте папку playwright-scraper в вашей любимой JavaScript IDE. IntelliJ IDEA или Visual Studio Code – отличные варианты. Внутри папки создайте файл script.js
, который вскоре будет содержать логику скрапинга:
Отлично! Теперь вы полностью готовы к работе с веб-скраппингом в Node.js с помощью Playwright.
Шаг № 2: Установка и настройка Playwright
В папке с проектом выполните следующую команду, чтобы установить Playwright:
npm install playwright
Затем установите браузер и все дополнительные зависимости, выполнив команду :
npx playwright install
Теперь откройте файл script.js
и добавьте следующий код, чтобы импортировать Playwright и запустить экземпляр браузера Chromium:
const { chromium } = require("playwright");
(async () => {
// initialize a Chromium browser
const browser = await chromium.launch({
headless: false, // comment out in production
});
// scraping logic goes here...
// close the browser and release resources
await browser.close();
})();
Опция headless: false
запускает браузер в режиме head. Это позволяет видеть, что делает скрипт, что полезно для отладки во время разработки.
Шаг № 3: Подключитесь к целевой странице
Инициализируйте новую страницу в браузере и используйте функцию goto()
для перехода на целевую страницу:
const page = await browser.newPage();
await page.goto("https://books.toscrape.com/catalogue/category/books/fantasy_19/index.html");
Если запустить скрипт в отладчике с точкой останова перед функцией close(), вы увидите, как браузер открывается и переходит на целевую страницу:
Потрясающе! Playwright управляет браузером, как и ожидалось.
Шаг #4: Реализация логики разбора данных
Прежде чем писать логику скраппинга, необходимо понять структуру страницы. Для этого откройте целевой сайт в браузере в окне инкогнито. Затем щелкните правой кнопкой мыши на элементе книги и выберите опцию “Осмотреть”.
Вот что вы должны увидеть в DevTools:
Выше вы можете заметить, что каждый элемент книги может быть выбран с помощью CSS-селектора .product_pod.
Поскольку страница содержит несколько книг, сначала инициализируйте массив, в котором будут храниться отсканированные данные:
books = []
Выберите их все и выполните итерацию, как показано ниже:
const bookElements = await page.locator(".product_pod").all();
for (const bookElement of bookElements) {
// extract book details...
}
Из каждого элемента книги, как показано на изображении выше, можно извлечь:
- URL-адрес книги из тега
<a>
- Название книги из узла
h3 a
- Изображение книги из элемента
.thumbnail
- Рейтинг книги из элемента
.star-rating
- Цена продукта из элемента
.product_price .price_color
- Доступность продукта из элемента
.availability
Теперь реализуйте логику скраппинга внутри цикла:
const urlElement = await bookElement.locator("a").first();
const url = makeAbsoluteURL(
await urlElement.getAttribute("href"),
"https://books.toscrape.com/catalogue/"
);
const titleElement = await bookElement.locator("h3 a");
const title = await titleElement.getAttribute("title");
const imageElement = await bookElement.locator(".thumbnail");
const image = makeAbsoluteURL(
await imageElement.getAttribute("src"),
"https://books.toscrape.com/"
);
const ratingElement = await bookElement.locator(".star-rating");
const ratingClass = await ratingElement.getAttribute("class");
let rating;
switch (true) {
case ratingClass.includes("One"):
rating = 1;
break;
case ratingClass.includes("Two"):
rating = 2;
break;
case ratingClass.includes("Three"):
rating = 3;
break;
case ratingClass.includes("Four"):
rating = 4;
break;
case ratingClass.includes("Five"):
rating = 5;
break;
default:
rating = null;
}
const priceElement = await bookElement.locator(
".product_price .price_color"
);
const price = (await priceElement.textContent()).trim();
const availabilityElement = await bookElement.locator(".availability");
const availability = (await availabilityElement.textContent()).trim();
В приведенном выше фрагменте используются функции getAttribute()
и textContent()
Playwright для извлечения определенных HTML-атрибутов и текста из HTML-узлов, соответственно. Обратите внимание на пользовательскую логику для получения оценки рейтинга.
Кроме того, поскольку URL-адреса на странице являются относительными, их можно преобразовать в абсолютные с помощью следующей пользовательской функции:
function makeAbsoluteURL(url, baseURL) {
// use a regular expression to remove any ../ or ../../ patterns
const cleanURL = url.replace(/(\.\.\/)+/, "");
// combine the base URL with the cleaned relative URL
return baseURL + cleanURL;
}
Затем заполните новый объект полученными данными и добавьте его в массив books:
const book = {
"url": url,
"title": title,
"image": image,
"rating": rating,
"price": price,
"availability": availability,
};
books.push(book);
Отлично! Теперь логика соскабливания Playwright завершена.
Шаг #4: Реализуйте логику ползания
Если вы посмотрите на целевой сайт, то заметите, что на некоторых страницах внизу есть кнопка “Далее”:
При нажатии на нее загружается следующая страница. Обратите внимание, что последняя страница пагинации не включает его по очевидным причинам.
Таким образом, вы можете реализовать логику веб-ползания с помощью цикла while (true)
, который:
- Соскабливает данные с текущей страницы
- Нажимает кнопку “Далее”, если она есть, и ждет, пока загрузится новая страница
- Повторяет процесс до тех пор, пока кнопка “Далее” больше не будет найдена
Ниже описано, как этого добиться:
while (true) {
// select the book elements ...
// select the "next" button and check if it is on the page
const nextElement = await page.locator("li.next a");
if ((await nextElement.count()) !== 0) {
// click the "next" button and go to the next page
await nextElement.click();
// wait for the page to have been loaded
await page.waitForLoadState("domcontentloaded")
} else {
break;
}
}
Потрясающе! Логика ползания реализована.
Шаг #5: Экспорт в CSV
Последний шаг – экспорт собранных данных в CSV-файл. Хотя вы можете сделать это с помощью ванильного Node.js, гораздо проще это сделать с помощью специализированной библиотеки, например fast-csv
.
Установите пакет fast-csv
, выполнив следующую команду:
npm install fast-csv
В начале файла scraping.js импортируйте необходимые модули:
const { writeToPath } = require("fast-csv");
Далее используйте следующий фрагмент, чтобы записать собранные данные в CSV-файл:
writeToPath("books.csv", books, { headers: true });
И вуаля! Скрипт веб-скрапинга Playwright готов.
Шаг №6: Соберите все вместе
Ваш файл script.js
должен содержать:
const { chromium } = require("playwright");
const { writeToPath } = require("fast-csv");
(async () => {
// initialize a Chromium browser
const browser = await chromium.launch({
headless: false, // comment out in production
});
// initialize a new page in the browser
const page = await browser.newPage();
// visit the target page
await page.goto(
"https://books.toscrape.com/catalogue/category/books/fantasy_19/index.html"
);
// where to store the scraped data
books = [];
while (true) {
// select the book elements
const bookElements = await page.locator(".product_pod").all();
// iterate over them to extract data from them
for (const bookElement of bookElements) {
// data extraction logic
const urlElement = await bookElement.locator("a").first();
const url = makeAbsoluteURL(
await urlElement.getAttribute("href"),
"https://books.toscrape.com/catalogue/"
);
const titleElement = await bookElement.locator("h3 a");
const title = await titleElement.getAttribute("title");
const imageElement = await bookElement.locator(".thumbnail");
const image = makeAbsoluteURL(
await imageElement.getAttribute("src"),
"https://books.toscrape.com/"
);
const ratingElement = await bookElement.locator(".star-rating");
const ratingClass = await ratingElement.getAttribute("class");
let rating;
switch (true) {
case ratingClass.includes("One"):
rating = 1;
break;
case ratingClass.includes("Two"):
rating = 2;
break;
case ratingClass.includes("Three"):
rating = 3;
break;
case ratingClass.includes("Four"):
rating = 4;
break;
case ratingClass.includes("Five"):
rating = 5;
break;
default:
rating = null;
}
const priceElement = await bookElement.locator(
".product_price .price_color"
);
const price = (await priceElement.textContent()).trim();
const availabilityElement = await bookElement.locator(".availability");
const availability = (await availabilityElement.textContent()).trim();
// populate a new book item with the scraped data and
// then add it to the array
const book = {
"url": url,
"title": title,
"image": image,
"rating": rating,
"price": price,
"availability": availability,
};
books.push(book);
}
// select the "next" button and check if it is on the page
const nextElement = await page.locator("li.next a");
if ((await nextElement.count()) !== 0) {
// click the "next" button and go to the next page
await nextElement.click();
// wait for the page to have been loaded
await page.waitForLoadState("domcontentloaded");
} else {
break;
}
}
// export the scraped data to CSV
writeToPath("books.csv", books, { headers: true });
// close the browser and release resources
await browser.close();
})();
function makeAbsoluteURL(url, baseURL) {
// use a regular expression to remove any ../ or ../../ patterns
const cleanURL = url.replace(/(\.\.\/)+/, "");
// combine the base URL with the cleaned relative URL
return baseURL + cleanURL;
}
Запустите его с помощью этой команды Node.js:
node script.js
В результате вы получите следующий файл books.csv
:
Миссия выполнена! Теперь пришло время посмотреть, как получить тот же результат с помощью Scrapy.
Как использовать Scrapy для веб-скрапинга
Выполните следующие шаги и узнайте, как создать простой веб-скрапер с помощью Scrapy. Для получения более подробной информации ознакомьтесь с нашим руководством по веб-скрейпингу с помощью Scrapy.
Шаг №1: Настройка проекта
Прежде чем приступить к работе, убедитесь, что у вас локально установлен Python 3. Если нет, скачайте его с официального сайта и установите.
Создайте папку для своего проекта и инициализируйте в ней виртуальную среду:
mkdir scrapy-scraper
cd scrapy-scraper
python -m venv venv
В Windows выполните следующую команду, чтобы активировать среду:
venv\Scripts\activate
Эквивалентно, на Unix или macOS выполните команду:
source venv/bin/activate
В активированной среде установите Scrapy с помощью:
pip install scrapy
Далее запустите приведенную ниже команду, чтобы создать проект Scrapy под названием “books_scraper”:
scrapy startproject books_scraper
Отлично! Вы настроены на веб-скраппинг с помощью Scrapy.
Шаг №2: Создание паука Scrapy
Войдите в папку проекта Scrapy и сгенерируйте нового паука для целевого сайта:
cd books_scraper
scrapy genspider books books.toscrape.com
Scrapy автоматически создаст все необходимые файлы. В частности, каталог books_scraper
теперь должен содержать следующую структуру файлов:
books_scraper/
│── __init__.py
│── items.py
│── middlewares.py
│── pipelines.py
│── settings.py
└── spiders/
│── __init__.py
└── books.py
Чтобы реализовать нужную логику скрапинга, замените содержимое books_scraper/spiders/books.py
следующим кодом:
import scrapy
class BooksSpider(scrapy.Spider):
name = "books"
allowed_domains = ["books.toscrape.com"]
start_urls = ["https://books.toscrape.com/catalogue/page-1.html"]
def parse(self, response):
# Extract book details
for book in response.css(".product_pod"):
yield {
"title": book.css("h3 a::attr(title)").get(),
"url": response.urljoin(book.css("h3 a::attr(href)").get()),
"image": response.urljoin(book.css(".thumbnail::attr(src)").get()),
"rating": book.css(".star-rating::attr(class)").get().split()[-1],
"price": book.css(".product_price .price_color::text").get(),
"availability": book.css(".availability::text").get().strip(),
}
# Handle pagination
next_page = response.css("li.next a::attr(href)").get()
if next_page:
yield response.follow(next_page, callback=self.parse)
Шаг № 3: Запуск паука
В папке books_scraper
в активированной виртуальной среде выполните следующую команду, чтобы запустить паука Scrapy и экспортировать собранные данные в CSV-файл:
scrapy crawl books -o books.csv
В результате будет создан файл books.csv
, содержащий отсканированные данные, точно так же, как и файл, созданный сценарием Playwright. И снова, миссия выполнена!
Scrapy против Playwright: Что лучше использовать?
Сценарий скраппинга Playwright требовал шести длительных шагов, а Scrapy – только трех. Это неудивительно, поскольку Scrapy предназначен для веб-скрапинга, в то время как Playwright – общий инструмент автоматизации браузера, используемый как для тестирования, так и для скрапинга.
В частности, ключевое различие заключалось в логике веб-ползания. Playwright требовал ручного взаимодействия и пользовательской логики для пагинации, в то время как Scrapy справляется с этим всего за несколько строк кода.
Короче говоря, в одном из этих сценариев выбирайте Scrapy, а не Playwright:
- Вам нужна крупномасштабная экстракция данных со встроенной поддержкой ползания.
- Производительность и скорость являются приоритетами, так как Scrapy оптимизирован для быстрых, параллельных запросов.
- Вы предпочитаете фреймворк, который сам справится с пагинацией, повторными попытками, извлечением данных в разных форматах и параллельным скраппингом.
Наоборот, предпочитаю Playwright, а не Scrapy, когда:
- Вам нужно извлекать данные из сайтов, перегруженных JavaScript и требующих рендеринга в браузере.
- Динамические взаимодействия, такие как бесконечная прокрутка, необходимы.
- Вы хотите получить больше контроля над взаимодействием с пользователем (например, в сложных схемах навигации при веб-скреппинге).
В качестве последнего шага в этом сравнении Scrapy и Playwright обратитесь к сводной таблице ниже:
Характеристики | Scrapy | Драматург |
---|---|---|
Разработано | Zyte + сообщество | Microsoft + сообщество |
Звезды GitHub | 54k+ | 69k+ |
Скачать | 380k+, еженедельно | 12M+, еженедельно |
Языки программирования | Python | Python, JavaScript, TypeScript, C# |
Главная цель | Веб-скраппинг и ползание | Автоматизация браузеров, тестирование и веб-скраппинг |
Рендеринг JavaScript | ❌ (возможно с некоторыми плагинами) | ✔️ |
Взаимодействие с браузером | ❌ (возможно с некоторыми плагинами) | ✔️ |
Автоаматизированное ползание | ✔️ | ❌ (требует ручного обращения) |
Интеграция прокси-сервера | Поддерживается | Поддерживается |
Параллельные запросы | Эффективный и легко настраиваемый | Ограниченно, но возможно |
Экспорт данных | CSV, JSON, XML и т.д. | Требуется пользовательская логика |
Ограничения как Playwright, так и Scrapy
И Scrapy, и Playwright – мощные инструменты для веб-скрапинга, но у каждого из них есть определенные ограничения.
Например, Scrapy не справляется с отбором динамического контента с сайтов, которые используют JavaScript для визуализации или получения данных. Поскольку многие современные сайты теперь требуют JavaScript, Scrapy более уязвима к обычным мерам по борьбе со скрапингом. Конечно, Playwright может работать с сайтами на JavaScript, но он сталкивается с такими проблемами, как запрет IP-адресов.
При большом количестве запросов могут сработать ограничители скорости, что приведет к отказам в запросах или даже запрету IP-адресов. Чтобы смягчить эту проблему, вы можете интегрировать прокси-сервер для ротации IP-адресов.
Если вам нужны надежные прокси-серверы, прокси-сети Bright Data доверяют компании из списка Fortune 500 и более 20 000 клиентов по всему миру. Их сеть включает в себя:
- Прокси для центров обработки данных: Более 770 000 IP-адресов центров обработки данных.
- Резидентные прокси: Более 72 миллионов жилых IP-адресов в более чем 195 странах.
- Прокси-провайдеры: Более 700 000 IP-адресов провайдеров.
- Мобильные прокси: Более 7 миллионов мобильных IP-адресов.
Еще одной проблемой в Playwright являются CAPTCHA, которые предназначены для блокировки автоматических ботов, работающих в браузерах. Чтобы преодолеть их, вы можете изучить решения для обхода CAPTCHA в Playwright.
Заключение
В этой статье блога Playwright vs Scrapy вы узнали о роли обеих библиотек в веб-скрапинге. Вы изучили их возможности для извлечения данных и сравнили их производительность в реальном сценарии пагинации.
Scrapy предоставляет все необходимое для парсинга данных и просмотра веб-сайтов, в то время как Playwright больше ориентирован на моделирование взаимодействия с пользователем.
Вы также узнали об их ограничениях, таких как запрет IP-адресов и CAPTCHA. К счастью, эти проблемы можно преодолеть с помощью прокси-серверов или специализированных решений для борьбы с ботами, таких как Bright Data’s CAPTCHA Solver.
Создайте бесплатную учетную запись Bright Data сегодня, чтобы изучить наши прокси и решения для скраппинга!
Кредитная карта не требуется