В этом руководстве вы увидите:
- Причины, по которым парсинг HTML в PHP может быть полезен
- Необходимые условия для начала работы над статьей
- Как разобрать HTML в PHP с помощью:
DomHTMLDocument
- Простой парсер HTML DOM
DomCrawler
для Symfony
- Сравнительная таблица трех подходов
Давайте погрузимся!
Зачем анализировать HTML в PHP?
Парсинг HTML в PHP включает в себя преобразование HTML-контента в структуру DOM(Document Object Model). После преобразования в формат DOM вы можете легко перемещаться по содержимому HTML и манипулировать им.
В частности, основными причинами для разбора HTML в PHP являются:
- Извлечение данных: Сбор определенного содержимого веб-страниц, например, текста или атрибутов элементов HTML.
- Автоматизация: Автоматизируйте такие задачи, как соскабливание контента, создание отчетов и сбор данных из HTML-контента.
- Обработка HTML-содержимого на стороне сервера: Разбор HTML для манипулирования, очистки или форматирования веб-контента на сервере перед его отображением в вашем приложении.
Откройте для себя лучшие библиотеки для разбора HTML!
Пререквизиты
Прежде чем приступить к написанию кода, убедитесь, что на вашем компьютере установлен PHP 8.4+. Убедиться в этом можно, выполнив следующую команду:
php -v
Результат должен выглядеть примерно так:
PHP 8.4.3 (cli) (built: Jan 19 2025 14:20:58) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.4.3, Copyright (c) Zend Technologies
with Zend OPcache v8.4.3, Copyright (c), by Zend Technologies
Далее вы хотите инициализировать проект Composer, чтобы упростить управление зависимостями. Если Composer не установлен в вашей системе, загрузите его и следуйте инструкциям по установке.
Сначала создайте новую папку для вашего проекта PHP HTML:
mkdir php-html-parser
Перейдите в папку в терминале и инициализируйте в ней проект Composer с помощью команды composer init
:
composer init
Во время этого процесса вам будет предложено ответить на несколько вопросов. Ответы по умолчанию подойдут, но при желании вы можете добавить более конкретные детали для вашего проекта по разбору PHP HTML.
Затем откройте папку с проектом в вашей любимой IDE. Visual Studio Code с расширением PHP или IntelliJ WebStorm – хорошие варианты для разработки на PHP.
Теперь добавьте пустой файл index.php
в папку проекта. Теперь структура вашего проекта должна выглядеть следующим образом:
php-html-parser/
├── vendor/
├── composer.json
└── index.php
Откройте файл index.php
и добавьте следующий код для инициализации проекта:
<?php
require_once __DIR__ . "/vendor/autoload.php";
// scraping logic...
Этот файл вскоре будет содержать логику для разбора HTML в PHP.
Теперь вы можете запустить свой скрипт с помощью этой команды:
php index.php
Отлично! Вы готовы приступить к разбору HTML в PHP. Теперь вы можете начать добавлять необходимую логику получения и разбора HTML в ваш скрипт.
Получение HTML в PHP
Прежде чем разбирать HTML в PHP, вам нужен HTML для разбора. В этом разделе мы рассмотрим два различных подхода к доступу к HTML-контенту в PHP.
С помощью CURL
PHP поддерживает cURL, популярный HTTP-клиент, используемый для выполнения HTTP-запросов. Включите расширение cURL или установите его в Linux с помощью:
sudo apt-get install php8.4-curl
Вы можете использовать cURL для отправки HTTP GET-запроса на онлайн-сервер и получения HTML-документа, возвращенного сервером.
Вот пример сценария, который выполняет простой GET-запрос и получает HTML-содержимое:
// initialize cURL session
$ch = curl_init();
// set the URL you want to make a GET request to
curl_setopt($ch, CURLOPT_URL, "https://www.scrapethissite.com/pages/forms/?per_page=100");
// return the response instead of outputting it
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// execute the cURL request and store the result in $response
$html = curl_exec($ch);
// close the cURL session
curl_close($ch);
// output the HTML response
echo $html;
Добавьте приведенный выше фрагмент в файл index.php
и запустите его. Получится следующий HTML-код:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Hockey Teams: Forms, Searching and Pagination | Scrape This Site | A public sandbox for learning web scraping</title>
<link rel="icon" type="image/png" href="/static/images/scraper-icon.png" />
<!-- Omitted for brevity... -->
</html>
Узнайте больше в нашем руководстве по cURL GET-запросам в PHP.
Из файла
Другой способ получить HTML-содержимое – сохранить его в специальном файле. Для этого:
- Зайдите на выбранную вами страницу в браузере
- Щелкните правой кнопкой мыши на странице
- Выберите опцию “Просмотр источника страницы”.
- Скопируйте и вставьте HTML в файл
В качестве альтернативы вы можете написать собственную HTML-логику в файле.
В этом примере мы предположим, что файл имеет имя index.html
. Он содержит HTML страницы “Хоккейные команды” из Scrape This Site, которая была получена ранее с помощью cURL:
Парсинг HTML в PHP: 3 подхода
В этом разделе вы узнаете, как использовать три различные библиотеки для разбора HTML в PHP:
- Использование
DomHTMLDocument
для ванильного PHP - Использование библиотеки Simple HTML DOM Parser
- Использование компонента
DomCrawler
в Symfony
Во всех трех случаях вы увидите, как разобрать либо HTML-строку, полученную через cURL, либо HTML-содержимое, считанное из локального файла index.html.
Затем вы узнаете, как использовать методы, предоставляемые каждой библиотекой разбора PHP HTML, чтобы выбрать все записи хоккейных команд на странице и извлечь из них данные:
В итоге мы получим список отсканированных записей хоккейных команд, содержащий следующие данные:
- Название команды
- Год
- Победы
- Потери
- Победа %
- Голы за (ГФ)
- Голы против (GA)
- Разница мячей
Вы можете извлечь их из таблицы HTML с помощью этой структуры:
Как видите, каждый столбец в строке таблицы имеет определенный класс. Вы можете извлекать из них данные, выбирая элементы с помощью их класса в качестве CSS-селектора, а затем извлекать их содержимое, обращаясь к их тексту.
Помните, что разбор HTML – это лишь один из этапов сценария веб-скрапинга. Для более глубокого погружения прочтите наш учебник по веб-скреппингу с помощью PHP.
Теперь давайте рассмотрим три различных подхода к разбору HTML в PHP.
Подход №1: С помощью DomHTMLDocument
PHP 8.4+ поставляется со встроенным классом DomHTMLDocument
. Он представляет HTML-документ и позволяет вам анализировать HTML-содержимое и перемещаться по дереву DOM. Посмотрите, как использовать его для разбора HTML в PHP!
Шаг №1: Установка и настройка
DomHTMLDocument
является частью стандартной библиотеки PHP. Тем не менее, чтобы использовать расширение DOM, вам нужно включить его или установить с помощью этой команды Linux:
sudo apt-get install php-dom
Дальнейшие действия не требуются. Теперь вы готовы использовать DomHTMLDocument
для разбора HTML в PHP.
Шаг №2: Парсинг HTML
Вы можете разобрать строку HTML следующим образом:
$dom = DOMHTMLDocument::createFromString($html);
Эквивалентно можно разобрать файл index.html
с помощью:
$dom = DOMHTMLDocument::createFromFile("./index.html");
$dom
– это объект DomHTMLDocument
, который предоставляет методы, необходимые для разбора данных.
Шаг № 3: Парсинг данных
Вы можете выбрать все записи хоккейной команды с помощью DOMHTMLDocument
, используя следующий подход:
// select each row on the page
$table = $dom->getElementsByTagName("table")->item(0);
$rows = $table->getElementsByTagName("tr");
// iterate through each row and extract data
foreach ($rows as $row) {
$cells = $row->getElementsByTagName("td");
// extracting the data from each column
$team = trim($cells->item(0)->textContent);
$year = trim($cells->item(1)->textContent);
$wins = trim($cells->item(2)->textContent);
$losses = trim($cells->item(3)->textContent);
$win_pct = trim($cells->item(5)->textContent);
$goals_for = trim($cells->item(6)->textContent);
$goals_against = trim($cells->item(7)->textContent);
$goal_diff = trim($cells->item(8)->textContent);
// create an array for the scraped team data
$team_data = [
"team" => $team,
"year" => $year,
"wins" => $wins,
"losses" => $losses,
"win_pct" => $win_pct,
"goals_for" => $goals_for,
"goals_against" => $goals_against,
"goal_diff" => $goal_diff
];
// print the scraped team data
print_r($team_data);
print ("n");
}
DOMHTMLDocument
не предлагает расширенных методов запроса. Поэтому вам придется полагаться на такие методы, как getElementsByTagName()
и ручную итерацию.
Ниже приводится описание используемых методов:
getElementsByTagName()
: Получение всех элементов заданного тега (например,<table>
,<tr>
или<td>
) в документе.item()
: Возвращает отдельный элемент из списка элементов, возвращенных функциейgetElementsByTagName()
.textContent
: Это свойство предоставляет необработанное текстовое содержимое элемента, позволяя извлекать видимые данные (например, название команды, год и т. д.).
Мы также использовали функцию trim()
, чтобы удалить лишние пробелы до и после текстового содержимого для получения более чистых данных.
При добавлении в index.php
вышеприведенный фрагмент приведет к такому результату:
Array
(
[team] => Boston Bruins
[year] => 1990
[wins] => 44
[losses] => 24
[win_pct] => 0.55
[goals_for] => 299
[goals_against] => 264
[goal_diff] => 35
)
// omitted for brevity...
Array
(
[team] => Detroit Red Wings
[year] => 1994
[wins] => 33
[losses] => 11
[win_pct] => 0.688
[goals_for] => 180
[goals_against] => 117
[goal_diff] => 63
)
Подход #2: Использование простого парсера HTML DOM
Simple HTML DOM Parser – это легкая PHP-библиотека, которая позволяет легко разбирать и манипулировать HTML-контентом. Библиотека активно поддерживается и имеет более 880 звезд на GitHub.
Шаг №1: Установка и настройка
Вы можете установить Simple HTML Dom Parser через Composer с помощью этой команды:
composer require voku/simple_html_dom
В качестве альтернативы вы можете вручную загрузить и включить файл simple_html_dom.php
в свой проект.
Затем импортируйте его в index.php
с помощью этой строки кода:
use vokuhelperHtmlDomParser;
Шаг №2: Парсинг HTML
Чтобы разобрать строку HTML, используйте метод file_get_html()
:
$dom = HtmlDomParser::str_get_html($html);
Для разбора index.html
вместо этого напишите file_get_html()
:
$dom = HtmlDomParser::file_get_html($str);
В результате HTML-содержимое будет загружено в объект $dom
, что позволит вам легко перемещаться по DOM.
Шаг № 3: Парсинг данных
Извлеките данные о хоккейной команде из HTML с помощью Simple HTML DOM Parser:
// find all rows in the table
$rows = $dom->findMulti("table tr.team");
// loop through each row to extract the data
foreach ($rows as $row) {
// extract data using CSS selectors
$team_element = $row->findOne(".name");
$team = trim($team_element->plaintext);
$year_element = $row->findOne(".year");
$year = trim($year_element->plaintext);
$wins_element = $row->findOne(".wins");
$wins = trim($wins_element->plaintext);
$losses_element = $row->findOne(".losses");
$losses = trim($losses_element->plaintext);
$win_pct_element = $row->findOne(".pct");
$win_pct = trim($win_pct_element->plaintext);
$goals_for_element = $row->findOne(".gf");
$goals_for = trim($goals_for_element->plaintext);
$goals_against_element = $row->findOne(".ga");
$goals_against = trim(string: $goals_against_element->plaintext);
$goal_diff_element = $row->findOne(".diff");
$goal_diff = trim(string: $goal_diff_element->plaintext);
// create an array with the extracted team data
$team_data = [
"team" => $team,
"year" => $year,
"wins" => $wins,
"losses" => $losses,
"win_pct" => $win_pct,
"goals_for" => $goals_for,
"goals_against" => $goals_against,
"goal_diff" => $goal_diff
];
// print the scraped team data
print_r($team_data);
print("n");
}
Простой HTML DOM Parser использует следующие функции:
findMulti()
: Выберите все элементы, определенные заданным CSS-селектором.findOne()
: Находит первый элемент, соответствующий заданному CSS-селектору.plaintext
: Атрибут для получения исходного текстового содержимого внутри HTML-элемента.
На этот раз мы использовали CSS-селекторы с более полной и надежной логикой. Тем не менее, результат будет таким же, как и в первоначальном PHP-подходе к разбору HTML.
Подход № 3: Использование компонента DomCrawler от Symfony
Компонент DomCrawler
от Symfony предоставляет простой способ анализа HTML-документов и извлечения из них данных.
Примечание: Компонент является частью фреймворка Symfony, но его можно использовать и отдельно, как мы и сделаем в этом разделе.
Шаг №1: Установка и настройка
Установите компонент DomCrawler
от Symfony с помощью этой команды Composer:
composer require symfony/dom-crawler
Затем импортируйте его в файл index.php:
use SymfonyComponentDomCrawlerCrawler;
Шаг №2: Парсинг HTML
Чтобы разобрать строку HTML, создайте экземпляр Crawler
с помощью метода html()
:
$crawler = new Crawler($html);
Для разбора файла используйте file_get_contents()
и создайте экземпляр Crawler
:
$crawler = new Crawler(file_get_contents("./index.html"));
Приведенные выше строки загружают HTML-контент в объект $crawler
, который предоставляет простые методы для обхода и извлечения данных.
Шаг № 3: Парсинг данных
Извлеките данные о хоккейной команде с помощью компонента DomCrawler
:
// select all rows within the table
$rows = $crawler->filter("table tr.team");
// loop through each row to extract the data
$rows->each(function ($row, $i) {
// extract data using CSS selectors
$team_element = $row->filter(".name");
$team = trim($team_element->text());
$year_element = $row->filter(".year");
$year = trim($year_element->text());
$wins_element = $row->filter(".wins");
$wins = trim($wins_element->text());
$losses_element = $row->filter(".losses");
$losses = trim($losses_element->text());
$win_pct_element = $row->filter(".pct");
$win_pct = trim($win_pct_element->text());
$goals_for_element = $row->filter(".gf");
$goals_for = trim($goals_for_element->text());
$goals_against_element = $row->filter(".ga");
$goals_against = trim($goals_against_element->text());
$goal_diff_element = $row->filter(".diff");
$goal_diff = trim($goal_diff_element->text());
// create an array with the extracted team data
$team_data = [
"team" => $team,
"year" => $year,
"wins" => $wins,
"losses" => $losses,
"win_pct" => $win_pct,
"goals_for" => $goals_for,
"goals_against" => $goals_against,
"goal_diff" => $goal_diff
];
// print the scraped team data
print_r($team_data);
print ("n");
});
Используются следующие методы DomCrawler
:
each()
: Итерация по списку выбранных элементов.filter()
: Выбор элементов на основе селекторов CSS.text()
: Извлечение текстового содержимого выбранных элементов.
Замечательно! Теперь вы мастер по разбору HTML в PHP.
Парсинг HTML в PHP: Сравнительная таблица
Вы можете сравнить три подхода к разбору HTML в PHP, рассмотренные здесь, в сводной таблице ниже:
DOMHTMLDocument | Простой парсер HTML DOM | DomCrawler для Symfony | |
---|---|---|---|
Тип | Родной компонент PHP | Внешняя библиотека | Компонент Symfony |
Звезды GitHub | – | 880+ | 4,000+ |
Поддержка XPath | ❌ | ✔️ | ✔️ |
Поддержка селекторов CSS | ❌ | ✔️ | ✔️ |
Кривая обучения | Низкий | От низкого до среднего | Средний |
Простота использования | Средний | Высокий | Высокий |
API | Основные | Рич | Рич |
Заключение
В этой статье вы узнали о трех подходах к разбору HTML в PHP, начиная от использования встроенных расширений и заканчивая сторонними библиотеками.
Хотя все эти решения работают, имейте в виду, что целевая веб-страница может использовать JavaScript для рендеринга. В этом случае простые подходы к разбору HTML, подобные тем, что представлены выше, не подойдут. Вместо этого вам понадобится полноценный браузер для скраппинга с расширенными возможностями разбора HTML, например Scraping Browser.
Хотите пропустить парсинг HTML и сразу получить данные? Посмотрите наши готовые наборы данных, охватывающие сотни сайтов!
Создайте бесплатную учетную запись Bright Data сегодня, чтобы протестировать наши решения по сбору данных и скрапбукингу с помощью бесплатной пробной версии!