В этой статье мы обсудим:
Веб-скрапинг с помощью JavaScript
Когда речь заходит о веб-скрfпинге, JavaScript служит довольно ограниченным решением. Во-первых, потому что вам придется запускать сценарий веб-скрапинга на JavaScript непосредственно из консоли браузера. Это не та операция, которую можно выполнить программно.
В частности, вы можете извлекать данные веб-страницы из консоли следующим образом:
Во-вторых, если бы вы хотели извлекать данные с других веб-страниц, вам пришлось бы загружать их через AJAX. Но не забывайте, что браузеры применяют к AJAX политику одинакового источника. Таким образом, с помощью JavaScript вы можете получить доступ к веб-страницам только в пределах одного источника.
Давайте разберемся, что это значит, на простом примере. Предположим, вы посещаете страницу с сайта brightdata.com
. Тогда ваш скрипт веб-скрапинга на JavaScript может загружать только веб-страницы, находящиеся в домене brightdata.com
.
Обратите внимание, что это вовсе не означает, что JavaScript не является идеальной технологией для веб-краулинга. На самом деле, Node.js позволяет запускать JavaScript на серверах и избегать двух представленных выше ограничений.
Давайте теперь разберемся, как можно построить веб-скрапер на JavaScript с помощью Node.js.
Предустановки
Прежде чем начать работу над приложением для веб-скрапинга на Node.js, необходимо выполнить следующий список предварительных условий:
- Node.js 18+ с npm 8+: Любая LTS (Long Term Support) версия Node.js 18+, включая npm, подойдет. Это учебное пособие основано на Node.js 18.12 с npm 8.19, которая представляет собой последнюю LTS-версию Node.js на момент написания статьи.
- IDE с поддержкой JavaScript. Для данного учебника выбрана Community Edition IntelliJ IDEA, но подойдет и любая другая IDE с поддержкой JavaScript и Node.js.
Перейдите по ссылкам выше и следуйте мастерам установки, чтобы настроить все необходимое. Вы можете проверить, что Node.js был установлен правильно, запустив приведенную ниже команду в терминале:
node -v
Эта команда должна вернуть что-то вроде этого:
v18.12.1
Аналогичным образом проверьте, что npm был установлен правильно с помощью
npm -v
Это должно вернуть строку вида:
8.19.2
Две команды выше указывают на версии Node.js и npm, доступные глобально на вашем компьютере.
Фантастика! Теперь вы готовы к тому, чтобы увидеть, как выполнить JavaScript веб-скрапинг в Node.js!
Лучшие JavaScript библиотеки для веб-скрапинга с помощью Node.js
Давайте рассмотрим лучшие библиотеки JavaScript для веб-скрапинга в Node.js:
- Axios: Простая в использовании библиотека, которая помогает выполнять HTTP-запросы на JavaScript. Вы можете использовать Axios как в браузере, так и в Node.js. Он является одним из самых популярных JavaScript HTTP-клиентов.
- Cheerio: Легкая библиотека, которая предоставляет jQuery-подобный API для изучения HTML и XML документов. Вы можете использовать Cheerio для разбора HTML-документа, выбора HTML-элементов и извлечения из них данных. Другими словами, Cheerio предлагает продвинутый API для веб-скрапинга.
- Selenium: Библиотека, поддерживающая несколько языков программирования, которую можно использовать для создания автоматизированного тестирования веб-приложений. Вы также можете использовать ее для создания безголового браузера для веб-скрапинга.
- Playwright: Инструмент для создания автоматизированных тестовых сценариев для веб-приложений, разработанный компанией Microsoft. Он позволяет инструктировать браузер для выполнения определенных действий. Таким образом, вы можете использовать Playwright для веб-скрапинга в качестве замены безголового браузера.
- Puppeteer: Инструмент для автоматизации тестирования веб-приложений, разработанный компанией Google. Puppeteer построен на базе протокола Chrome DevTools. Как и Selenium, а также Playwright, он позволяет программно взаимодействовать с браузером, как это делал бы пользователь. Узнать больше о различиях между Selenium и Puppeteer можно по этой ссылке.
Создание веб-скрапера на JavaScript в Node.js
Отсюда вы узнаете, как создать веб-скрапер на JavaScript в Node.js, способный автоматически извлекать данные с сайта. В качестве целевой веб-страницы будет выбрана домашняя страница Bright Data. Целью процесса веб-скрапинга в Node.js будет выбор интересующих нас HTML-элементов на странице, извлечение из них данных и их преобразование в более полезный формат.
На момент написания статьи вот как выглядит домашняя страница Bright Data:
Как вы могли заметить, главная страница Bright Data содержит множество данных и информации в различных форматах — от текстовых описаний до изображений. Кроме того, она содержит полезные ссылки. Сейчас вы узнаете, как извлечь все эти данные.
Давайте рассмотрим, как получить данные с помощью Node.js в пошаговом руководстве по веб-скрапингу!
Шаг 1: Создайте проект Node.js
Сначала создайте папку, в которой будет находиться ваш проект по веб-скрапингу с помощью Node.js:
mkdir web-scraper-nodejs
Теперь у вас должен быть пустой каталог web-scraper-nodejs
. Обратите внимание, что вы можете дать папке проекта любое имя. Войдите в папку с помощью:
cd web-scraper-nodejs
Теперь инициализируйте проект npm с помощью:
npm init -y
Эта команда создаст для вас новый проект npm. Обратите внимание, что флаг -y
необходим для того, чтобы npm инициализировал проект по умолчанию без интерактивного процесса. Если вы опустите флаг -y
, в терминале нужно будет ответить на несколько вопросов.
web-scraper-nodejs
теперь должен содержать package.json
, который выглядит следующим образом:
{
"name": "web-scraper-nodejs",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
Теперь создайте файл index.js
в корневой папке вашего проекта и инициализируйте его, как показано ниже:
// index.js
console.log("Hello, World!")
Этот файл JavaScript будет содержать логику веб-скрапинга Node.js.
Откройте файл package.json
и добавьте следующий сценарий в раздел scripts
:
"start": "node index.js"
Теперь вы можете выполнить приведенную ниже команду в терминале для запуска вашего сценария Node.js:
npm run start
Это должно вернуться:
Hello, World!
Это означает, что ваше приложение Node.js работает правильно. Теперь откройте проект в вашей IDE и приготовьтесь писать логику скрапинга в Node.js!
Если вы являетесь пользователем IntelliJ IDEA, то должны увидеть следующее:
Шаг 2: Установите Axios и Cheerio
Пришло время установить зависимости, необходимые для реализации веб-скрапера на Node.js. Чтобы выяснить, какие библиотеки JavaScript следует в этом случае использовать, посетите целевую веб-страницу, щелкните правой кнопкой мыши на пустом разделе и выберите опцию «Inspect». Это должно открыть в браузере окно DevTools. На вкладке «Network» изучите раздел Fetch/XHR.
Выше показаны запросы AJAX, выполненные целевой веб-страницей. Если вы откроете три выполненные сайтом XHR-запроса, то увидите, что они не возвращают интересных данных. Другими словами, нужные данные непосредственно встроены в исходный код веб-страницы. Обычно это происходит с сайтами с рендерингом на стороне сервера.
Целевая веб-страница не использует JavaScript для получения данных или рендеринга. Таким образом, вам не нужен инструмент, способный выполнять JavaScript в браузере. Другими словами, для извлечения данных с целевой веб-страницы не нужно использовать библиотеку безголового браузера. Вы, конечно, можете ее использовать, но это совершенно не обязательно.
Поскольку библиотеки, предоставляющие возможности безголового браузера, открывают веб-страницы в браузере, это вызывает увеличение нагрузки на ваш компьютер. Это происходит потому, что браузеры являются тяжелыми приложениями. Вы можете легко избежать этого, выбрав Cheerio вместе с Axios.
Итак, установите cheerio
и axios
с помощью:
npm install cheerio axios
Затем импортируйте cheerio
и axios
, добавив следующие две строки кода в файл index.js
:
// index.js
const cheerio = require("cheerio")
const axios = require("axios")
Давайте теперь напишем скрипт для веб-скрапинга на Node.js, который выполняет его с помощью Cheerio и Axios!
Шаг 3: Загрузите целевой сайт
Используйте Axios для подключения к целевому сайту с помощью следующих строк кода:
// downloading the target web page
// by performing an HTTP GET request in Axios
const axiosResponse = await axios.request({
method: "GET",
url: "https://brightdata.com",
})
Благодаря методу Axios под названием request()
вы можете выполнить любой HTTP-запрос. Например, если вы хотите загрузить исходный код веб-страницы, вам нужно выполнить HTTP GET-запрос к ее URL. Обычно Axios немедленно возвращает Promise. Вы можете подождать Promise
и получить его значение синхронно с помощью ключевого слова await
.
Обратите внимание, что в случае неудачи при выполнении request()
будет выдана ошибка Error
. Это может произойти по нескольким причинам — от недействительного URL до временной недоступности сервера. Также не забывайте, что некоторые из них реализуют меры по борьбе со скрапингом. Одна из самых популярных включает блокировку запросов, которые не имеют действительного HTTP-заголовка User-Agent
. Узнайте больше о User-Agent
для веб-скрапинга.
По умолчанию Axios будет использовать следующий User-Agent
:
axios <axios_version>
Это не то, как выглядит используемый браузером User-Agent
, поэтому антискрапинговые технологии могут обнаружить и заблокировать веб-скрапер на Node.js.
Установите действительный заголовок User-Agent
в Axios, добавив следующий атрибут к объекту, передаваемому в request()
:
headers: {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
}
Атрибут headers
позволяет установить любой HTTP-заголовок в Axios.
Теперь ваш файл index.js
должен выглядеть следующим образом:
// index.js
const cheerio = require("cheerio")
const axios = require("axios")
async function performScraping() {
// downloading the target web page
// by performing an HTTP GET request in Axios
const axiosResponse = await axios.request({
method: "GET",
url: "https://brightdata.com",
headers: {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
}
})
}
performScraping()
Обратите внимание, что вы можете использовать await
только в функциях, помеченных async
. Вот почему вы должны встроить свою логику веб-скрапинга на JavaScript в функцию async
performScraping()
.
Теперь давайте потратим некоторое время на анализ целевой веб-страницы, чтобы определить стратегию для веб-скрапинга.
Шаг 4: Изучите HTML-страницу
Если вы посмотрите на главную страницу Bright Data, то увидите список отраслей, в которых можно использовать Bright Data. Это полезные для веб-скрапинга данные.
Кликните правой кнопкой мышки на один из HTML-элементов и выберите «Inspect»:
Проанализировав HTML-код выбранной ноды, вы увидите, что карточка является HTML-элементом <a>
. В частности, <a>
содержит:
- HTML-элемент
<figure>
содержит связанное с отраслью изображение - HTML-элемент
<div>
содержит название отрасли
Теперь обратите внимание на классы CSS, которые характеризуют эти элементы HTML. Используя их, вы сможете определить селекторы CSS, необходимые для выбора этих элементов HTML в DOM. Обратите внимание, что карточки .e-container
содержатся в <div>
под названием .elementor-element-7a85e3a8
. Затем, определив карточку, вы можете извлечь все ее данные с помощью следующих селекторов CSS:
.elementor-image-box-img img
.elementor-image-box-content .elementor-image-box-title
Аналогично, вы можете применить ту же логику для определения селекторов CSS, необходимых для:
- Извлеките причины, по которым Bright Data является лидером отрасли.
- Выберите причины, которые делают клиентский опыт, предлагаемый Bright Data, лучшим на рынке.
Другими словами, у целевой веб-страницы есть три цели для скрапинга:
- Данные об отраслях, в которых вы можете воспользоваться преимуществами Bright Data.
- Данные о причинах, по которым Bright Data является лидером отрасли.
- Данные о том, почему Bright Data обеспечивает лучший клиентский опыт в отрасли.
Шаг 5: Выбор HTML-элементов с помощью Cheerio
Cheerio предлагает несколько способов выбора HTML-элементов на веб-странице. Но сначала необходимо инициализировать Cheerio с помощью:
// parsing the HTML source of the target web page with Cheerio
const $ = cheerio.load(axiosResponse.data)
Метод Cheerio load()
принимает HTML-контент в строковой форме. Обратите внимание, что объект ответа Axios содержит данные, возвращенные HTTP-запросом, в атрибуте data
. В данном случае data
будет хранить исходный код HTML веб-страницы, возвращенной сервером. Итак, вы передаете axiosResponse.data
в load()
для инициализации Cheerio.
Вы должны называть переменную Cheerio $
, потому что Cheerio имеет практически тот же синтаксис, что и jQuery. Таким образом, вы сможете копировать фрагменты jQuery из интернета.
Вы можете выбрать элемент HTML с помощью Cheerio, используя его класс с:
const htmlElement = $(".elementClass")
Аналогично, вы можете получить HTML-элемент по ID с помощью:
const htmlElement = $("#elementId")
Вы можете выбирать HTML-элементы, передавая в $
любой допустимый CSS-селектор, точно так же, как это делается в jQuery. Вы также можете объединить логику выбора с помощью метода find()
:
// retrieving the list of industry cards
const industryCards = $(".elementor-element-7a85e3a8").find(".e-container")
find()
предоставляет вам доступ к потомкам текущего HTML-элемента, отфильтрованным с помощью селектора CSS. Затем вы можете выполнить итерации по списку нод Cheerio с помощью метода each()
, как показано ниже:
// iterating over the list of industry cards
$(".elementor-element-7a85e3a8")
.find(".e-container")
.each((index, element) => {
// scraping logic...
})
Теперь давайте узнаем, как использовать Cheerio для извлечения данных из интересующих нас элементов HTML.
Шаг 6: Получите данные с целевой веб-страницы с помощью Cheerio
Вы можете расширить логику, показанную ранее, чтобы извлечь нужные данные из выбранных HTML-элементов, как показано ниже:
// initializing the data structure
// that will contain the scraped data
const industries = []
// scraping the "Learn how web data is used in your market" section
$(".elementor-element-7a85e3a8")
.find(".e-container")
.each((index, element) => {
// extracting the data of interest
const pageUrl = $(element).attr("href")
const image = $(element).find(".elementor-image-box-img img").attr("data-lazy-src")
const name = $(element).find(".elementor-image-box-content .elementor-image-box-title").text()
// filtering out not interesting data
if (name && pageUrl) {
// converting the data extracted into a more
// readable object
const industry = {
url: pageUrl,
image: image,
name: name
}
// adding the object containing the scraped data
// to the industries array
industries.push(industry)
}
})
Этот сниппет Node.js для веб-скрапинга выбирает все отраслевые карточки на главной странице Bright Data. Затем он перебирает все HTML-элементы карточки. Для каждой карточки он собирает URL веб-страницы, связанной с карточкой, изображение и название отрасли. Благодаря методам attr()
и text()
из Cheerio можно получить значение HTML-атрибута и текст соответственно. Наконец, он сохраняет собранные данные в объекте и добавляет их в массив под названием industries.
В конце цикла each()
industries будет содержать все интересующие данные, связанные с первой целью скрапинга. Теперь давайте посмотрим, как достичь и двух других целей.
Данные, подтверждающие, что Bright Data является лидером отрасли, можно получить следующим образом:
const marketLeaderReasons = []
// scraping the "What makes Bright Data
// the undisputed industry leader" section
$(".elementor-element-ef3e47e")
.find(".elementor-widget")
.each((index, element) => {
const image = $(element).find(".elementor-image-box-img img").attr("data-lazy-src")
const title = $(element).find(".elementor-image-box-title").text()
const description = $(element).find(".elementor-image-box-description").text()
const marketLeaderReason = {
title: title,
image: image,
description: description,
}
marketLeaderReasons.push(marketLeaderReason)
})
Наконец, вы можете собрать всю информацию о том, почему можно быть уверенным в том, что Bright Data предлагает своим клиентам лучшее обслуживание:
const customerExperienceReasons = []
// scraping the "The best customer experience in the industry" section
$(".elementor-element-288b23cd .elementor-text-editor")
.find("li")
.each((index, element) => {
const title = $(element).find("strong").text()
// since the title is part of the text, you have
// to remove it to get only the description
const description = $(element).text().replace(title, "").trim()
const customerExperienceReason = {
title: title,
description: description,
}
customerExperienceReasons.push(customerExperienceReason)
})
Поздравляем! Вы только что узнали, как достичь всех трех целей веб-скрапинга на Node.js!
Помните, что вы можете извлекать данные с других веб-страниц, следуя ссылкам, которые вы обнаружили на текущей странице. Поэтому вы можете определить логику веб-скрапинга для извлечения полезной информации и с этих страниц.
industries
, marketLeaderReasons
, customerExperienceReasons
будут хранить все извлеченные данные в объектах JavaScript. Давайте узнаем, как преобразовать их в более полезный формат.
Шаг 7: Преобразование извлеченных данных в JSON
JSON — один из лучших форматов данных, когда речь идет о JavaScript. Это связано с тем, что JSON имеет непосредственное отношение к JavaScript и является форматом, обычно используемым API для приема или возврата данных. Итак, вам может понадобиться преобразовать данные, полученные в результате скрапинга с помощью JavaScript, в JSON. Вы можете легко добиться этого с помощью приведенной ниже логики:
// trasforming the scraped data into a general object
const scrapedData = {
industries: industries,
marketLeader: marketLeaderReasons,
customerExperience: customerExperienceReasons,
}
// converting the scraped data object to JSON
const scrapedDataJSON = JSON.stringify(scrapedData)
Сначала необходимо создать объект JavaScript, содержащий все данные, полученные с помощью веб-скрапинга. Затем вы можете преобразовать этот объект JavaScript в JSON с помощью JSON.stringify()
.
scrapedDataJSON
будет содержать следующие данные JSON:
{
"industries": [
{
"url": "https://brightdata.com/use-cases/ecommerce",
"image": "https://brightdata.com/wp-content/uploads/2022/07/E_commerce.svg",
"name": "E-commerce"
},
// ...
{
"url": "https://brightdata.com/use-cases/data-for-good",
"image": "https://brightdata.com/wp-content/uploads/2022/07/Data_for_Good_N.svg",
"name": "Data for Good"
}
],
"marketLeader": [
{
"title": "Most reliable",
"image": "https://brightdata.com/wp-content/uploads/2022/01/reliable.svg",
"description": "Highest quality data, best network uptime, fastest output "
},
// ...
{
"title": "Most efficient",
"image": "https://brightdata.com/wp-content/uploads/2022/01/efficient.svg",
"description": "Minimum in-house resources needed"
}
],
"customerExperience": [
{
"title": "You ask, we develop",
"description": "New feature releases every day"
},
// ...
{
"title": "Tailored solutions",
"description": "To meet your data collection goals"
}
]
}
Поздравляем! Вы начали с подключения к веб-сайту и теперь можете легко извлечь его данные и преобразовать их в JSON. Теперь вы готовы взглянуть на полный сценарий Node.js для веб-скрапинга.
Собираем все вместе
Вот как выглядит веб-скрапер Node.js:
// index.js
const cheerio = require("cheerio")
const axios = require("axios")
async function performScraping() {
// downloading the target web page
// by performing an HTTP GET request in Axios
const axiosResponse = await axios.request({
method: "GET",
url: "https://brightdata.com/",
headers: {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
}
})
// parsing the HTML source of the target web page with Cheerio
const $ = cheerio.load(axiosResponse.data)
// initializing the data structures
// that will contain the scraped data
const industries = []
const marketLeaderReasons = []
const customerExperienceReasons = []
// scraping the "Learn how web data is used in your market" section
$(".elementor-element-7a85e3a8")
.find(".e-container")
.each((index, element) => {
// extracting the data of interest
const pageUrl = $(element).attr("href")
const image = $(element).find(".elementor-image-box-img img").attr("data-lazy-src")
const name = $(element).find(".elementor-image-box-content .elementor-image-box-title").text()
// filtering out not interesting data
if (name && pageUrl) {
// converting the data extracted into a more
// readable object
const industry = {
url: pageUrl,
image: image,
name: name
}
// adding the object containing the scraped data
// to the industries array
industries.push(industry)
}
})
// scraping the "What makes Bright Data
// the undisputed industry leader" section
$(".elementor-element-ef3e47e")
.find(".elementor-widget")
.each((index, element) => {
// extracting the data of interest
const image = $(element).find(".elementor-image-box-img img").attr("data-lazy-src")
const title = $(element).find(".elementor-image-box-title").text()
const description = $(element).find(".elementor-image-box-description").text()
// converting the data extracted into a more
// readable object
const marketLeaderReason = {
title: title,
image: image,
description: description,
}
// adding the object containing the scraped data
// to the marketLeaderReasons array
marketLeaderReasons.push(marketLeaderReason)
})
// scraping the "The best customer experience in the industry" section
$(".elementor-element-288b23cd .elementor-text-editor")
.find("li")
.each((index, element) => {
// extracting the data of interest
const title = $(element).find("strong").text()
// since the title is part of the text, you have
// to remove it to get only the description
const description = $(element).text().replace(title, "").trim()
// converting the data extracted into a more
// readable object
const customerExperienceReason = {
title: title,
description: description,
}
// adding the object containing the scraped data
// to the customerExperienceReasons array
customerExperienceReasons.push(customerExperienceReason)
})
// trasforming the scraped data into a general object
const scrapedData = {
industries: industries,
marketLeader: marketLeaderReasons,
customerExperience: customerExperienceReasons,
}
// converting the scraped data object to JSON
const scrapedDataJSON = JSON.stringify(scrapedData)
// storing scrapedDataJSON in a database via an API call...
}
performScraping()
Как здесь показано, вы можете создать веб-скрапер на Node.js, использовав для этого менее чем за 100 строк кода. С помощью Cheerio и Axios вы можете загрузить веб-страницу HTML, спарсить ее и автоматически получить все данные. Затем вы можете легко преобразовать собранные данные в JSON. Вот что такое веб-скрапинг на Node.js.
Запустите свой веб-скрапер в Node.js с помощью:
npm run start
Вуаля! Вы только что узнали, как выполнять веб-скрапинг с помощью JavaScript в Node.js!
Заключение
В этом уроке вы узнали, почему веб-скрапинг с помощью JavaScript не является идеальным решением, и почему именно Node.js, как раз, оптимальный вариант. Кроме того, вы увидели, что нужно для создания сценария веб-скрапинга на Node.js, и как можно получить данные из интернета с помощью JavaScript. В частности, вы познакомились с тем, как использовать Cheerio и Axios для создания JavaScript-приложения для веб-скрапинга в Node.js на реальном примере. Как вы убедились, веб-скрапинг с помощью Node.js требует минимальное количество кода.
Но имейте в виду, что веб-скрапинг может оказаться не таким уж простым делом. Причина в том, что существует множество проблем, которые вам, возможно, придется решать. В частности, все большее распространение получают антискрапинговые и антибот-решения. К счастью, вы можете легко избежать всего этого с помощью передового инструмента для веб-скрапинга нового поколения, предоставляемого компанией Bright Data. Не хотите иметь дело со сложностями современного веб-скрапинга? Изучите наши наборы данных.
Если вы хотите узнать больше о том, как избежать блокировки, воспользуйтесь веб-прокси из одного из нескольких прокси-сервисов, доступных в Bright Data, или же попробуйте продвинутый Web Unlocker.
Не уверены, какой продукт выбрать? Свяжитесь с отделом продаж и найдите подходящее решение для веб-скрапинга для вас.
Кредитная карта не требуется