Встроеная в PHP библиотека DOMDocument
DOMDocument
это встроенная библиотека PHP, предоставляющая удобные функции для работы с HTML
и XML
. Она позволяет загружать документы, обращаться к элементам по тегам, классам или идентификаторам, а также извлекать данные и модифицировать документы. Благодаря DOMDocument
вы можете легко работать с HTML-страницами и XML-файлами.
Работа с DOM
осуществляется в объектно-ориентированном стиле. Для начала работы с ним нужно создать объект DOMDocument
.
DOMDocument
позволяет конвертировать HTML-файл в объект, который можно легко обходить и запрашивать различные элементы.
В связке с DOMDocument
работает например DOMXPath
, который использует выражения путей для выбора узлов. Для начала нужно создать объект класса DOMDocument
, который передастся дальше в DOMXPath
.
DOMDocument
используется для общей работы с HTML-документами, а DOMXPath
для более продвинутых задач, связанных с использованием выражений XPath
для выбора узлов.
Принцип работы
При создании нового объекта DOMDocument
:
$dom = new domDocument;
Вызывается конструктор DOMDocument=>__construct
, имеющий два необязательных аргумента, которые указывают на версию документа и его кодировку:
$dom->loadHTML(код_html);
Если загрузка данных прошла успешно, то будет возвращено FALSE
.
После того как данные загружены, чаще всего осуществляется их разбор. Для этого используется сам DOMDocument
или дополнительные классы классы, некоторые из важных:
DOMDocument
основной классDOMNode
DOM из HTML представляет собой древовидную структуру, состоящую из отдельных узлов. Эти узлы могут быть любого типа, например, элемент, текст, комментарий, атрибут и т.д.DOMNode
является базовым классом, от которого наследуются все типы классов узловDOMElement
класс расширяетDOMNode
класс, который может представлять элементы в HTML — разметке. ОбъектомDOMElement
может быть любой элемент, такой как изображение, div, span, table и т.д.DOMXPath
класс позволяет искать элементы более детальноDOMNodeList
Практические примеры
Вот запрос curl:
header('Content-Type:application/json');
$url = "https://hmarketing.ru";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$res = curl_exec($ch);
curl_close($ch);
Переменная $res
содержит весь HTML-код с веб-страницы.
Выбор по ID
Предположим, я хочу найти количество div
у элемента с id="chat"
:
$dom = new DomDocument();
$dom->loadHTML($res);
// DOMElement
$table = $dom->getElementById('chat');
// DOMNodeList
$child_elements = $table->getElementsByTagName('div');
$row_count = $child_elements->length;
Выбор тега по его имени
DOMDocument
и DOMElement
классы имеют метод, getElementsByTagName()
который позволяет нам выбирать элементы, используя имя тега. Например, если нужно получить все h1
со страницы, мы можем использовать эту функцию:
$dom = new DomDocument();
$dom->loadHTML($res);
$h1s = $dom->getElementsByTagName('h1');
foreach( $h1s as $h1 ) {
echo $h1->textContent . "\n";
}
Найти элементы с определенным классом
В Javascript
метод querySelectorAll()
позволяет легко выбирать любые элементы с помощью селектора CSS
. В PHP это не так просто. Вместо этого мы должны использовать DOMXpath
класс для запроса и обхода дерева DOM
.
Выберим все div
с class="title"
:
$dom = new DomDocument();
$dom->loadHTML($res);
$xpath = new DOMXpath($dom);
$tables = $xpath->query("//div[contains(@class,'title')]");
$count = $tables->length;
Если вы новичок в XPath
, эта шпаргалка содержит широкий перечень CSS и JS селекторов XPath
выражений.
Извлечь ссылки со страницы
Найти все ссылки на странице:
$dom = new DomDocument();
$dom->loadHTML($res);
$links = $dom->getElementsByTagName('a');
$urls = [];
foreach($links as $link) {
$url = $link->getAttribute('href');
$parsed_url = parse_url($url);
if( isset($parsed_url['path'])) {
$urls[] = $url;
}
}
var_dump($urls);
Вставка нового HTML-элемента в документ
В этом примере мы увидим, как добавить изображение со ссылкой после первого абзаца:
$dom = new DomDocument();
$dom->loadHTML($res);
$ps = $dom->getElementsByTagName('p');
$first_para = $ps->item(0);
$html_to_add = '<p>123456</p>';
$dom_to_add = new DOMDocument();
$dom_to_add->loadHTML($html_to_add);
$new_element = $dom_to_add->documentElement;
$imported_element = $dom->importNode($new_element, true);
$first_para->parentNode->insertBefore($imported_element, $first_para->nextSibling);
$output = $dom->saveHTML();
echo $output;
Удаление элемента из документа
Чтобы удалить элемент из HTML, мы можем использовать removeChild()
метод из DOMElement
:
$dom = new DomDocument();
$dom->loadHTML($res);
$documentElement = $dom->documentElement;
$xpath = new DOMXpath($dom);
$elems = $xpath->query("//div[@class='title']");
foreach( $elems as $elem ) {
$elem->parentNode->removeChild($elem);
}
echo $dom->saveHTML();
Здесь мы выполнили XPath
запрос, чтобы найти все элементы класса class="title"
. Затем мы удаляем каждый узел из документа, перебирая DOMNodeList
объект с помощью цикла.
Манипулирующие атрибуты
Классы и идентификаторы, не единственные атрибуты, к которым мы можем получить доступ в PHP DOM
. DOMElement
имеет несколько функций, которые могут получать, устанавливать или удалять атрибуты элемента. Эти методы выглядят аналогично Javascript
. Так что вам будет легко понять.
getAttribute($attribute_name)
получить значение атрибутаsetAttribute($attribute_name, $attribute_value)
установить значение атрибутаhasAttribute($attribute_name)
проверяет, имеет ли элемент определенный атрибут и возвращает истину или ложь
$dom = new DomDocument();
$dom->loadHTML($res);
$elem = $dom->getElementsByTagName('span')->item(0);
if( $elem->hasAttribute('data-action') ) {
echo 'Значение атрибута "' . $elem->getAttribute('data-action') . '"';
$elem->setAttribute('data-action', 'hide');
echo 'Обновленное значение атрибута "' . $elem->getAttribute('data-action') . '"';
}