DiDOM - простая и быстрая библиотека для парсинга HTML.
- Установка
- Быстрый старт
- Создание нового документа
- Поиск элементов
- Проверка наличия элемента
- Вывод содержимого
- Создание нового элемента
- Получение родителя
- Работа с атрибутами элемента
- Сравнение элементов
- Работа с кэшем
- Сравнение с другими парсерами
Для установки DiDOM выполните команду:
composer require imangazaliev/didom
use DiDom\Document;
$document = new Document('http://www.news.com/', true);
$posts = $document->find('.post');
foreach($posts as $post) {
echo $post->text(), "\n";
}
DiDom позволяет загрузить HTML несколькими способами:
// в первом параметре передается строка с HTML
$document = new Document($html);
// путь к файлу
$document = new Document('page.html', true);
// или URL
$document = new Document('http://www.example.com/', true);
Второй параметр указывает на то, что загружается файл. По умолчанию - false
.
$document = new Document();
$document->loadHtml($html);
$document->loadHtmlFile('page.html');
$document->loadHtmlFile('http://www.example.com/');
В качестве выражения для поиска можно передать CSS-селектор или XPath-путь. Для этого в первом параметре нужно передать само выражение, а во втором - его тип (по умолчанию - Query::TYPE_CSS
):
use DiDom\Document;
use DiDom\Query;
...
// CSS-селектор
$posts = $document->find('.post');
// XPath-путь
$posts = $document->find("//div[contains(@class, 'post')]", Query::TYPE_XPATH);
$posts = $document('.post');
$posts = $document->xpath("//*[contains(concat(' ', normalize-space(@class), ' '), ' post ')]");
Можно осуществлять поиск и внутри элемента:
echo $document->find('.post')[0]->find('h2')[0]->text();
Если элементы, соответствующие заданному выражению, найдены, метод вернет массив с экземплярами класса DiDom\Element
, иначе - пустой массив. При желании можно получить массив объектов DOMElement
. Для этого необходимо передать в качестве третьего параметра false
.
Проверить наличие элемента можно с помощью метода has()
:
if ($document->has('.post')) {
// код
}
Если нужно проверить наличие элемента, а затем получить его, то можно сделать так:
if ($document->has('.post')) {
$elements = $document->find('.post');
// код
}
но быстрее так:
if (count($elements = $document->find('.post')) != 0) {
// код
}
т.к. в первом случае выполняется два запроса.
$posts = $document->find('.post');
echo $posts[0]->html();
$html = (string) $posts[0];
$html = $document->format()->html();
Метод format()
отсутствует у элемента, поэтому, если нужно вывести отформатированный HTML-код элемента, необходимо сначала преобразовать его в документ:
$html = $element->toDocument()->format()->html();
$posts = $document->find('.post');
echo $posts[0]->text();
use DiDom\Element;
$element = new Element('span', 'Hello');
// выведет "<span>Hello</span>"
echo $element->html();
Первым параметром передается название элемента, вторым - его значение (необязательно), третьим - атрибуты элемента (необязательно).
Пример создания элемента с атрибутами:
$attributes = ['name' => 'description', 'placeholder' => 'Enter description of item'];
$element = new Element('textarea', 'Text', $attributes);
Элемент можно создать и из экземпляра класса DOMElement
:
use DiDom\Element;
use DOMElement;
$domElement = new DOMElement('span', 'Hello');
$element = new Element($domElement);
$document = new Document($html);
$element = $document->createElement('span', 'Hello');
$document = new Document($html);
$element = $document->find('input[name=email]')[0];
// получение родителя
$parent = $element->parent();
// bool(true)
var_dump($document->is($parent));
$name = $element->tag;
$element->setAttribute('name', 'username');
$element->attr('name', 'username');
$element->name = 'username';
$username = $element->getAttribute('value');
$username = $element->attr('value');
$username = $element->name;
Если атрибут не найден, вернет null
.
if ($element->hasAttribute('name')) {
// код
}
if (isset($element->name)) {
// код
}
$element->removeAttribute('name');
unset($element->name);
$element = new Element('span', 'hello');
$element2 = new Element('span', 'hello');
// bool(true)
var_dump($element->is($element));
// bool(false)
var_dump($element->is($element2));
Кэш - массив XPath-выражений, полученных из CSS.
use DiDom\Query;
...
$xpath = Query::compile('h2');
$compiled = Query::getCompiled();
// array('h2' => '//h2')
var_dump($compiled);
Query::setCompiled(['h2' => '//h2']);