Как парсить HTML/XML в PHP? Сравнение подходов, которое сэкономит вам часы
Вы когда-нибудь сталкивались с задачей извлечь данные с чужого сайта или разобрать сложный XML-конфиг? Если да, то вы знаете, как быстро «ручной» парсинг с помощью strpos() и explode() превращается в кошмар. Ошибка в одном теге — и весь паук ломается. Хорошая новость: PHP предоставляет несколько мощных и элегантных решений. Плохая — легко запутаться, какое из них выбрать. В этой статье мы разложим по полочкам все основные подходы к парсингу HTML и XML в PHP, сравним их производительность и удобство, и вы наконец-то поймёте, какой инструмент взять в свой арсенал.
Почему не стоит писать свой велосипед?
Первый порыв новичка — написать свой парсер на регулярных выражениях. Да, для одноразовой задачи с идеально ровным HTML это может сработать. Но как только на странице появляются вложенные теги, комментарии или, не дай бог, невалидный HTML (а его 90% в реальном мире), регулярки пасуют. Вместо того чтобы тратить время на отладку десятков паттернов, воспользуйтесь готовыми библиотеками. Они уже решили все проблемы за вас.
Подход №1: DOMDocument — «тяжёлая артиллерия» для HTML
DOMDocument — это встроенное расширение PHP, которое строит полноценное DOM-дерево документа. Его главная суперсила — умение работать с кривым HTML. Вы просто передаёте ему строку, и он пытается её исправить. Идеально для парсинга реальных веб-страниц.
Вот как выглядит классический пример: извлекаем все ссылки из HTML.
<?php
$html = '<a href="https://pythonlib.ru">PythonLib</a>
<a href="https://php.net">PHP.net</a>';
$dom = new DOMDocument();
// Подавляем ошибки парсинга невалидного HTML
libxml_use_internal_errors(true);
$dom->loadHTML($html);
libxml_clear_errors();
$xpath = new DOMXPath($dom);
$links = $xpath->query('//a/@href');
foreach ($links as $link) {
echo $link->nodeValue . "\n";
}
?>
Плюсы:
- Работает с любым, даже сломанным HTML.
- Полная поддержка XPath — можно делать сложные запросы.
- Встроен в PHP, не требует установки.
Минусы:
- Потребляет много памяти при больших документах.
- Медленнее альтернатив на простых задачах.
- Неудобный API для простого извлечения данных.
Подход №2: SimpleXML — лёгкость и элегантность для XML
Если вы работаете с заведомо валидным XML (RSS-ленты, API-ответы, конфиги), SimpleXML — ваш лучший друг. Он превращает XML в объект, к элементам которого можно обращаться как к свойствам, а к атрибутам — как к элементам массива.
Пример парсинга RSS-ленты:
<?php
$xml = '<rss>
<channel>
<item>
<title>Новость 1</title>
<link>https://example.com/1</link>
</item>
<item>
<title>Новость 2</title>
<link>https://example.com/2</link>
</item>
</channel>
</rss>';
$feed = simplexml_load_string($xml);
foreach ($feed->channel->item as $item) {
echo $item->title . ': ' . $item->link . "\n";
}
?>
Плюсы:
- Невероятно простой и интуитивный синтаксис.
- Минимальное потребление памяти.
- Отлично подходит для чтения конфигурационных файлов.
Минусы:
- Не умеет работать с невалидным HTML.
- Сложно добавлять/изменять узлы.
- Нет поддержки XPath (хотя есть
SimpleXMLElement::xpath()).
Подход №3: Symfony DomCrawler — профессиональный инструмент для веб-скрапинга
Когда встроенных средств становится мало, на сцену выходит Symfony DomCrawler. Это часть экосистемы Symfony, но её можно использовать и как отдельную библиотеку. Она сочетает мощь DOMDocument с удобным API, похожим на jQuery или CSS-селекторы.
Установка через Composer:
composer require symfony/dom-crawler symfony/css-selector
Пример: находим все заголовки h2 на странице.
<?php
require 'vendor/autoload.php';
use Symfony\Component\DomCrawler\Crawler;
$html = '<body><h2>Заголовок 1</h2><h2 class="special">Заголовок 2</h2></body>';
$crawler = new Crawler($html);
$headings = $crawler->filter('h2.special');
foreach ($headings as $heading) {
echo $heading->textContent . "\n"; // Выведет: Заголовок 2
}
?>
Плюсы:
- Поддержка CSS-селекторов — пишите как в jQuery.
- Удобные методы для извлечения текста, атрибутов, HTML.
- Легко комбинируется с HTTP-клиентом (например, Guzzle).
Минусы:
- Требует установки через Composer.
- Чуть медленнее чистого DOMDocument на простых задачах.
- Избыточен для разового парсинга одного XML-файла.
Сравнительная таблица: что выбрать?
| Критерий | DOMDocument | SimpleXML | Symfony DomCrawler |
|---|---|---|---|
| Тип документа | HTML (кривой) / XML | Только валидный XML | HTML (кривой) / XML
БлогиРекомендаций по книгамЧитайте также |