Как вы анализируете и обрабатываете HTML / XML в PHP?

Как можно анализировать HTML/XML и извлекать из него информацию?

29 ответов


собственные расширения XML

Я предпочитаю использовать один из собственные расширения XML поскольку они поставляются в комплекте с PHP, обычно быстрее, чем все сторонние библиотеки, и дают мне весь необходимый контроль над разметкой.

дом

расширение DOM позволяет работать с XML-документами через DOM API с PHP 5. Это реализация объектной модели документа W3C Core Level 3, платформа - и язык-нейтральный интерфейс, позволяющий программам и скриптам динамически получать доступ и обновлять содержимое, структуру и стиль документов.

DOM способен анализировать и изменять реальный мир (сломанный) HTML, и он может делать запросов XPath. Он основан на libxml.

требуется некоторое время, чтобы стать продуктивным с DOM, но это время стоит ИМО. Поскольку DOM является агностическим интерфейсом языка, вы найдете реализации во многих языки, поэтому, если вам нужно изменить язык программирования, скорее всего, вы уже знаете, как использовать DOM API этого языка.

простой пример использования можно найти в захват атрибута href элемента a и общий концептуальный обзор можно найти в DOMDocument в php

как использовать расширение DOM был широко освещен на StackOverflow, так что если вы решите использовать его, вы можете быть уверены большинство из проблем, с которыми вы сталкиваетесь, можно решить путем поиска/просмотра переполнения стека.

XMLReader

расширение XMLReader является синтаксическим анализатором XML. Считыватель действует как курсор, идущий вперед по потоку документов и останавливающийся на каждом узле по пути.

XMLReader, как и DOM, основан на libxml. Я не знаю, как запустить модуль парсера HTML, поэтому шансы использовать XMLReader для разбора сломанного HTML могут быть меньше надежный, чем использование DOM, где вы можете явно сказать ему использовать модуль анализатора HTML libxml.

простой пример использования можно найти в получение всех значений из тегов h1 с помощью php

XML Parser

это расширение позволяет создавать синтаксические анализаторы XML, а затем определять обработчики для различных событий XML. Каждый синтаксический анализатор XML также имеет несколько параметров, которые можно настроить.

библиотека синтаксического анализатора XML также основана на libxml и реализует Сакс стиль XML push parser. Это может быть лучший выбор для управления памятью, чем DOM или SimpleXML, но будет сложнее работать, чем анализатор pull, реализованный XMLReader.

SimpleXml

расширение SimpleXML предоставляет очень простой и легко используемый набор инструментов для преобразования XML в объект, который может быть обработан с помощью обычных селекторов свойств и итераторов массива.

SimpleXML-это опция, когда вы знаете, что HTML допустим XHTML. Если вам нужно разобрать сломанный HTML, даже не рассматривайте SimpleXml, потому что он задохнется.

простой пример использования можно найти в простая программа для CRUD узлов и значений узлов xml-файла и множество дополнительных примеров в руководстве по PHP.


сторонние библиотеки (на основе libxml)

Если вы предпочитаете использовать 3rd-party lib, я бы предложил использовать lib, который фактически использует дом/libxml внизу вместо синтаксического анализа строк.

FluentDom

FluentDOM предоставляет jQuery-подобный интерфейс fluent XML для DOMDocument в PHP. Селекторы написаны в XPath или CSS (используя конвертер CSS в XPath). Текущие версии расширяют DOM, реализующие стандартные интерфейсы, и добавляют функции из жизненного уровня DOM. FluentDOM может загружать форматы как JSON, CSV, JsonML, RabbitFish и другие. Можно установить через Composer.

HtmlPageDom

Wa72\HtmlPageDom ' - это библиотека PHP для легкой манипуляции HTML для использования документов требуется DomCrawler из Symfony2 компоненты для прохождения Дерево DOM и расширяет его путем добавления методов для манипулирования DOM дерево документов HTML.

phpQuery (не обновляется годами)

phpQuery-это серверная, цепная, CSS3 селекторная объектная модель документа (DOM) API на основе библиотеки jQuery JavaScript, написанной в PHP5, и предоставляет дополнительный интерфейс командной строки (CLI).

Также см.:https://github.com/electrolinux/phpquery

Zend_Dom

Zend_Dom предоставляет инструменты для работы с документами и структурами DOM. В настоящее время мы предлагаем Zend_Dom_Query, который предоставляет унифицированный интерфейс для запроса документов DOM с использованием селекторов XPath и CSS.

QueryPath

QueryPath-это библиотека PHP для управления XML и HTML. Он предназначен для работы не только с локальными файлами, но и с веб-службами и ресурсами базы данных. Он реализует большую часть интерфейса jQuery (включая селекторы CSS-стиля), но он сильно настроен для использования на стороне сервера. Может быть установить через Composer.

fDOMDocument

fDOMDocument расширяет стандартный DOM для использования исключений во всех случаях ошибок вместо предупреждений или уведомлений PHP. Они также добавляют различные пользовательские методы и ярлыки для удобства и упрощения использования DOM.

sabre / xml

sabre / xml-это библиотека, которая обертывает и расширяет классы XMLReader и XMLWriter для создания простой системы отображения "xml для объекта / массива" и шаблона проектирования. Запись и чтение XML является однопереходным и поэтому может быть быстрым и требует низкой памяти на больших xml-файлов.

FluidXML

FluidXML-это библиотека PHP для управления XML с кратким и плавным API. Он использует XPath и беглый шаблон программирования, чтобы быть веселым и эффективным.


3rd-Party (не libxml-based)

преимущество построения на DOM / libxml заключается в том, что вы получаете хорошую производительность из коробки, потому что вы основаны на собственном расширении. Однако не все сторонние библиотеки идут по этому пути. Некоторые из них перечислены ниже

PHP простой парсер HTML DOM

  • парсер HTML DOM, написанный на PHP5+, позволяет очень легко манипулировать HTML!
  • требуется PHP 5+.
  • поддерживает недопустимый код HTML.
  • найти теги на HTML-странице с селекторами, как jQuery.
  • извлечение содержимого из HTML в одной строке.

Я вообще не рекомендую этот парсер. Кодовая база ужасна, а сам парсер довольно медленный, и память голодна. Не все селекторы jQuery (например,селекторы дочерних элементов) возможны. Любая из библиотек на основе libxml должна превзойти это легко.

PHP для анализатор HTML

PHPHtmlParser-это простой, гибкий HTML-парсер, который позволяет выбирать теги с помощью любого селектора css, например jQuery. Цель состоит в том, чтобы помочь в разработке инструментов, которые требуют быстрый, простой способ ломать html, является ли это действительным или нет! Этот проект был первоначально поддержан sunra / php-simple-html-dom-parser, но поддержка, похоже, остановилась, поэтому этот проект является моей адаптацией его предыдущего работа.

опять же, я бы не рекомендовал этот парсер. Это довольно медленно с высоким использованием процессора. Также нет функции для очистки памяти созданных объектов DOM. Эти проблемы масштабируются, в частности, с вложенными циклами. Сама документация является неточной и с ошибками, без ответов на исправления с 14 Apr 16.

Ганон

  • универсальный токенизатор и синтаксический анализатор HTML/XML/RSS DOM
    • возможность манипулировать элементами и их атрибутами
    • поддерживает недопустимые HTML и UTF8
  • может выполнять расширенные CSS3-подобные запросы к элементам (например, jQuery -- namespaces supported)
  • HTML beautifier (например, HTML Tidy)
    • минимизировать CSS и Javascript
    • Сортировать атрибуты, изменить регистр символов, правильный отступ и т. д.
  • расширяемый
    • разбор документов с помощью обратных вызовов на основе текущего символа / токена
    • операции, разделенные на меньшие функции для легкого переопределения
  • быстро и легко

никогда им не пользовался. Не могу сказать, хорошо ли это.


HTML 5

вы можете использовать выше для разбора HTML5, но могут быть причуды из-за разметки HTML5 позволяет. Итак, для HTML5 вы хотите рассмотреть возможность использования выделенного парсера, например

html5lib

реализации Python и PHP синтаксического анализатора HTML на основе спецификации WHATWG HTML5 для максимальной совместимости с основными настольными веб-браузерами.

мы можем увидеть больше выделенных синтаксических анализаторов после завершения HTML5. Существует также blogpost от W3 под названием How - To для синтаксического анализа html 5 это стоит проверить из.


веб-сервисы

Если вы не хотите программировать PHP, вы также можете использовать веб-службы. В общем, я нашел для них очень мало полезности, но это только я и мои варианты использования.

YQL

веб-служба YQL позволяет приложениям запрашивать, фильтровать и комбинировать данные из различных источников в Интернете. Операторы YQL имеют SQL-подобный синтаксис, знакомый любому разработчику с базой данных опыт.

ScraperWiki.

внешний интерфейс ScraperWiki позволяет извлекать данные в форме, которую вы хотите использовать в интернете или в собственных приложениях. Вы также можете извлечь информацию о состоянии любого скребка.


Регулярные Выражения

последний и порекомендовала, вы можете извлечь данные из HTML с помощью регулярные выражения. В общее использование регулярных выражений в HTML не рекомендуется.

большинство фрагментов, которые вы найдете в интернете, чтобы соответствовать разметке, хрупкие. В большинстве случаев они работают только для очень конкретного фрагмента HTML. Крошечные изменения разметки, такие как добавление пробелов, добавление или изменение атрибутов в теге, могут привести к сбою регулярного выражения, когда оно неправильно написано. Вы должны знать, что вы делаете, прежде чем использовать RegEx на HTML.

синтаксические анализаторы HTML уже знают синтаксические правила HTML. Регулярные выражения должны преподаваться для каждого нового регулярного выражения, которое вы пишете. RegEx в некоторых случаях прекрасны, но это действительно зависит от вашего варианта использования.

вы может писать более надежные Парсеры, но пишу полной и достоверной пользовательский парсер с регулярными выражениями-пустая трата времени, когда вышеупомянутые библиотеки уже существуют и делают намного лучшую работу над этим.

см. Также Разбор Html Ктулху Путь


- книги

Если вы хотите потратить немного денег, посмотри

Я не связан с PHP Architect или авторами.


попробовать простой парсер HTML DOM

  • парсер HTML DOM, написанный на PHP 5+, который позволяет вам манипулировать HTML очень простым способом!
  • требуется PHP 5+.
  • поддерживает недопустимый HTML.
  • найти теги на HTML-странице с селекторами, как jQuery.
  • извлечение содержимого из HTML в одном линия.
  • скачать


примеры:

как получить HTML элементы:

// Create DOM from URL or file
$html = file_get_html('http://www.example.com/');

// Find all images
foreach($html->find('img') as $element)
       echo $element->src . '<br>';

// Find all links
foreach($html->find('a') as $element)
       echo $element->href . '<br>';


как изменить элементы HTML:

// Create DOM from string
$html = str_get_html('<div id="hello">Hello</div><div id="world">World</div>');

$html->find('div', 1)->class = 'bar';

$html->find('div[id=hello]', 0)->innertext = 'foo';

echo $html;


извлечение содержимого из HTML:

// Dump contents (without tags) from HTML
echo file_get_html('http://www.google.com/')->plaintext;


Выскабливая Slashdot:

// Create DOM from URL
$html = file_get_html('http://slashdot.org/');

// Find all article blocks
foreach($html->find('div.article') as $article) {
    $item['title']     = $article->find('div.title', 0)->plaintext;
    $item['intro']    = $article->find('div.intro', 0)->plaintext;
    $item['details'] = $article->find('div.details', 0)->plaintext;
    $articles[] = $item;
}

print_r($articles);

просто использовать DOMDocument->loadHTML() и покончим с этим. алгоритм синтаксического анализа HTML libxml довольно хорош и быстр, и вопреки распространенному мнению, не задыхается от искаженного HTML.


почему вы не должны и когда вы должны использовать регулярные выражения?

во-первых, распространенное неправильное название: Regexps не для "извлечение" HTML-код. Однако с помощью регулярных выражений можно "экстракт" данные. Они для этого и созданы. Основным недостатком извлечения regex HTML над соответствующими инструментами SGML или базовыми синтаксическими анализаторами XML являются их синтаксические усилия и различная надежность.

рассмотреть это делает несколько надежным регулярное выражение извлечения HTML:

<a\s+class="?playbutton\d?[^>]+id="(\d+)".+?    <a\s+class="[\w\s]*title
[\w\s]*"[^>]+href="(http://[^">]+)"[^>]*>([^<>]+)</a>.+?

является менее читаемым, чем простой эквивалент phpQuery или QueryPath:

$div->find(".stationcool a")->attr("title");

однако существуют конкретные случаи использования, где они могут помочь.

  • многие интерфейсы обхода DOM не показывают HTML-комментарии <!--, которые, однако, иногда являются более полезными якорями для извлечения. В частности псевдо-HTML вариации <$var> или выпарки SGML легки для того чтобы приручить с регулярное выражение.
  • часто регулярные выражения могут сохранять постобработку. Однако HTML-объекты часто требуют ручного ухода.
  • и, наконец, для extremely простые задачи как и извлечение

иногда даже рекомендуется предварительно извлечь фрагмент HTML с помощью обычного выражения /<!--CONTENT-->(.+?)<!--END-->/ и обработайте остаток, используя более простые интерфейсы синтаксического анализатора HTML.

Примечание: у меня на самом деле есть это app, где я использую синтаксический анализ XML и регулярные выражения в качестве альтернативы. Только на прошлой неделе разбор PyQuery сломался, и регулярное выражение все еще работало. Да, странно, и я не могу объяснить это сам. Но так случилось.
Поэтому, пожалуйста, не голосуйте за реальные соображения, только потому, что они не соответствуют мему regex=evil. но давайте также не будем слишком много голосовать. Это просто заметка на эту тему.


phpQuery и QueryPath чрезвычайно похожи в репликации fluent jQuery API. Вот почему они являются двумя из самых простых подходов к правильно синтаксический анализ HTML в PHP.

примеры для QueryPath

в основном вы сначала создаете запрашиваемое дерево DOM из строки HTML:

 $qp = qp("<html><body><h1>title</h1>..."); // or give filename or URL

результирующий объект содержит полное древовидное представление HTML-документа. Он может быть пройден с помощью методов DOM. Но общий подход-использовать селекторы CSS, как в jQuery:

 $qp->find("div.classname")->children()->...;

 foreach ($qp->find("p img") as $img) {
     print qp($img)->attr("src");
 }

в основном вы хотите использовать простой #id и .class или DIV селекторы тегов для ->find(). Но вы также можете использовать XPath-выражения заявления, которые иногда быстрее. Также типичные методы jQuery, такие как ->children() и ->text() и особенно ->attr() упростить извлечение правильных фрагментов HTML. (И уже имеют свои сущности SGML декодированный.)

 $qp->xpath("//div/p[1]");  // get first paragraph in a div

QueryPath также позволяет вводить новые теги в поток (->append), а затем вывод и исправление обновленного документа (->writeHTML). Он может не только анализировать искаженный HTML, но и различные диалекты XML (с пространствами имен), и даже извлекать данные из микроформатов HTML (XFN, vCard).

 $qp->find("a[target=_blank]")->toggleClass("usability-blunder");

.

phpQuery или QueryPath?

обычно QueryPath лучше подходит для обработки документов. В то время как phpQuery также реализует некоторые псевдо-методы AJAX (только HTTP-запросы), чтобы больше походить на jQuery. Говорят, что phpQuery часто быстрее, чем QueryPath (из-за меньшего количества общих функций).

для получения дополнительной информации о различиях см. это сравнение на машине wayback от tagbyte.org. (Исходный источник пропал без вести, поэтому вот ссылка на интернет-архив. Да, вы все еще можете найти недостающие страницы, люди.)

и вот всестороннее введение QueryPath.

преимущества

  • простота и надежность
  • простые в использовании альтернативы ->find("a img, a object, div a")
  • правильные данные unescaping (по сравнению с регулярным выражением grepping)

Simple HTML DOM-отличный парсер с открытым исходным кодом:

simplehtmldom.на SourceForge

он обрабатывает элементы DOM объектно-ориентированным способом, и новая итерация имеет много покрытия для несоответствующего кода. Есть также некоторые большие функции, как вы видели в JavaScript, такие как функция "Найти", которая вернет все экземпляры элементов этого имени тега.

Я использовал это в ряде инструментов, тестируя его на многих разных типы веб-страниц, и я думаю, что это отлично работает.


один общий подход, который я не видел здесь, - это запустить HTML через Tidy, который можно установить для выплевывания гарантированного действительного XHTML. Тогда вы можете использовать любую старую библиотеку XML на нем.

но к вашей конкретной проблеме, вы должны взглянуть на этот проект:http://fivefilters.org/content-only/ -- это модифицированная версия читабельности алгоритм, который предназначен для извлечения только текста (не заголовков и нижних колонтитулов) со страницы.


за 1a и 2: я бы проголосовал за новый Symfony Componet class DOMCrawler ( DomCrawler ). Этот класс позволяет выполнять запросы, подобные селекторам CSS. Взгляните на эту презентацию для реальных примеров:новости-о-symfony2-мире.

компонент предназначен для автономной работы и может использоваться без Symfony.

единственным недостатком является то, что он будет работать только с PHP 5.3 или новее.


Это обычно называется экран выскабливание, кстати. Библиотеки я использовал для это простой парсер HTML Dom.


мы создали довольно много искателей для наших нужд раньше. В конце концов, это обычно простые регулярные выражения, которые делают вещь лучше всего. Хотя библиотеки, перечисленные выше, хороши по причине их создания, если вы знаете, что ищете, регулярные выражения-более безопасный способ, так как вы можете обрабатывать также недействительные HTML-код/XHTML структуры, которые потерпят неудачу, если будут загружены через большинство парсеров.


рекомендую PHP простой парсер HTML DOM.

Он действительно имеет хорошие функции, такие как:

foreach($html->find('img') as $element)
       echo $element->src . '<br>';

Это звучит как хорошее описание задачи W3C XPath-выражения технологии. Легко выразить такие запросы, как " return all href атрибуты img теги, вложенные в <foo><bar><baz> elements."Не будучи фанатом PHP, я не могу сказать вам, в какой форме XPath может быть доступен. Если вы можете вызвать внешнюю программу для обработки HTML-файла, вы должны иметь возможность использовать версию командной строки XPath. Для быстрого вступления см. http://en.wikipedia.org/wiki/XPath.


сторонние альтернативы SimpleHtmlDom, которые используют DOM вместо синтаксического анализа строк:phpQuery, Zend_Dom, QueryPath и FluentDom.


Да, вы можете использовать simple_html_dom для этой цели. Однако я много работал с simple_html_dom, особенно для веб-слом и нашел его слишком уязвимым. Он выполняет основную работу, но я не буду рекомендовать его в любом случае.

Я никогда не использовал curl для этой цели, но то, что я узнал, это то, что curl может делать работу намного эффективнее и гораздо более прочным.

пожалуйста, проверьте эту ссылку:выскабливание-веб-сайты-с-curl


QueryPath хорошо, но будьте осторожны с "состоянием отслеживания", потому что если вы не поняли, что это значит, это может означать, что вы тратите много времени на отладку, пытаясь выяснить, что произошло и почему код не работает.

это означает, что каждый вызов результирующего набора изменяет результирующий набор в объекте, он не является цепным, как в jquery, где каждая ссылка является новым набором, у вас есть один набор, который является результатом вашего запроса, и каждый вызов функции изменяет это единый набор.

чтобы получить jQuery-подобное поведение, вам нужно разветвиться, прежде чем вы сделаете операцию фильтра/изменения, это означает, что она будет отражать то, что происходит в jquery гораздо ближе.

$results = qp("div p");
$forename = $results->find("input[name='forename']");

$results теперь содержит результирующий набор для input[name='forename'] не исходный запрос "div p" это меня сильно споткнулось, и я обнаружил, что QueryPath отслеживает фильтров и находит и все, что изменяет ваши результаты и сохраняет их в объекте. вам нужно сделайте это вместо

$forename = $results->branch()->find("input[name='forname']")

затем $results не будет изменен, и вы можете повторно использовать результирующий набор снова и снова, возможно, кто-то с гораздо большими знаниями может немного прояснить это, но в основном это похоже на то, что я нашел.


Расширенный Html Dom простой HTML дом замена, которая предлагает тот же интерфейс, но она основана на DOM, что означает, что ни одна из связанных проблем с памятью не возникает.

Он также имеет полную поддержку CSS, в том числе jQuery расширения.


Я создал библиотеку с именем PHPPowertools / DOM-Query, что позволяет сканировать HTML5 и XML-документы так же, как вы делаете с jQuery.

под капотом, он использует symfony/DomCrawler для преобразования селекторов CSS в XPath-выражения селекторы. Он всегда использует один и тот же DomDocument, даже при передаче одного объекта другому, для обеспечения достойной производительности.


пример использования :

namespace PowerTools;

// Get file content
$htmlcode = file_get_contents('https://github.com');

// Define your DOMCrawler based on file string
$H = new DOM_Query($htmlcode);

// Define your DOMCrawler based on an existing DOM_Query instance
$H = new DOM_Query($H->select('body'));

// Passing a string (CSS selector)
$s = $H->select('div.foo');

// Passing an element object (DOM Element)
$s = $H->select($documentBody);

// Passing a DOM Query object
$s = $H->select( $H->select('p + p'));

// Select the body tag
$body = $H->select('body');

// Combine different classes as one selector to get all site blocks
$siteblocks = $body->select('.site-header, .masthead, .site-body, .site-footer');

// Nest your methods just like you would with jQuery
$siteblocks->select('button')->add('span')->addClass('icon icon-printer');

// Use a lambda function to set the text of all site blocks
$siteblocks->text(function( $i, $val) {
    return $i . " - " . $val->attr('class');
});

// Append the following HTML to all site blocks
$siteblocks->append('<div class="site-center"></div>');

// Use a descendant selector to select the site's footer
$sitefooter = $body->select('.site-footer > .site-center');

// Set some attributes for the site's footer
$sitefooter->attr(array('id' => 'aweeesome', 'data-val' => 'see'));

// Use a lambda function to set the attributes of all site blocks
$siteblocks->attr('data-val', function( $i, $val) {
    return $i . " - " . $val->attr('class') . " - photo by Kelly Clark";
});

// Select the parent of the site's footer
$sitefooterparent = $sitefooter->parent();

// Remove the class of all i-tags within the site's footer's parent
$sitefooterparent->select('i')->removeAttr('class');

// Wrap the site's footer within two nex selectors
$sitefooter->wrap('<section><div class="footer-wrapper"></div></section>');

[...]

поддерживаемые методы :


  1. переименовано 'select', для очевидного причины
  2. переименовано в "void", так как "empty" является зарезервированным словом в PHP

Примечание :

библиотека также включает свой собственный загрузчик нулевой конфигурации для библиотек, совместимых с PSR-0. Включенный пример должен работать из коробки без какой-либо дополнительной конфигурации. Кроме того, вы можете использовать его с композитором.


Я написал синтаксический анализатор XML общего назначения, который может легко обрабатывать файлы GB. Он основан на XMLReader и очень прост в использовании:

$source = new XmlExtractor("path/to/tag", "/path/to/file.xml");
foreach ($source as $tag) {
    echo $tag->field1;
    echo $tag->field2->subfield1;
}

вот репозиторий github:XmlExtractor


на в HTML5, HTML5 lib был оставлен в течение многих лет. Единственная библиотека HTML5, которую я могу найти с недавними обновлениями и записями обслуживания, -в HTML5-версии PHP который был только что доставлен в бета 1.0 чуть более недели назад.


вы можете попробовать использовать что-то вроде HTML Tidy для очистки любого "сломанного" HTML и преобразования HTML в XHTML, который затем можно проанализировать с помощью синтаксического анализатора XML.


другой вариант вы можете попробовать это QueryPath. Он вдохновлен jQuery, но на сервере в PHP и в Друпал.


XML_HTMLSax довольно стабилен-даже если он больше не поддерживается. Другой вариант может быть передать вам HTML через Html Tidy и затем проанализировать его с помощью стандартных инструментов XML.


на Symfony framework имеет пакеты, которые могут анализировать HTML, и вы можете использовать стиль CSS для выбора Домс вместо XPath-выражения.


существует много способов обработки HTML / XML DOM, большинство из которых уже упоминалось. Поэтому я не буду пытаться перечислить их сам.

Я просто хочу добавить, что лично я предпочитаю использовать расширение DOM и почему:

  • iit оптимально использует преимущество производительности базового кода C
  • это OO PHP (и позволяет мне подкласс его)
  • это довольно низкий уровень (что позволяет мне использовать его в качестве не раздутый фундамент для более продвинутого поведения)
  • он обеспечивает доступ к каждой части DOM (в отличие от, например. SimpleXml, который игнорирует некоторые из менее известных функций XML)
  • он имеет синтаксис, используемый для обхода DOM, который похож на синтаксис, используемый в собственном Javascript.

и пока я пропускаю возможность использовать селекторы CSS для DOMDocument, есть довольно простой и удобный способ добавить эту функцию: подклассы DOMDocument и добавление JS-like querySelectorAll и querySelector методы подкласса.

для разбора селекторов, я рекомендую использовать очень минималистичный компонент CssSelector С Symfony framework. Этот компонент просто переводит селекторы CSS в селекторы XPath, которые затем могут быть поданы в DOMXpath для получения соответствующего узла.

затем вы можете использовать этот (до сих пор очень низкий уровень) подкласс в качестве основы для более высоких классов, предназначенных например. очень парсить определенные типы XML или добавить более jQuery-подобное поведение.

код ниже выходит прямо из моего DOM-библиотека запросов и использует технику, которую я описал.

для синтаксического анализа HTML:

namespace PowerTools;

use \Symfony\Component\CssSelector\CssSelector as CssSelector;

class DOM_Document extends \DOMDocument {
    public function __construct($data = false, $doctype = 'html', $encoding = 'UTF-8', $version = '1.0') {
        parent::__construct($version, $encoding);
        if ($doctype && $doctype === 'html') {
            @$this->loadHTML($data);
        } else {
            @$this->loadXML($data);
        }
    }

    public function querySelectorAll($selector, $contextnode = null) {
        if (isset($this->doctype->name) && $this->doctype->name == 'html') {
            CssSelector::enableHtmlExtension();
        } else {
            CssSelector::disableHtmlExtension();
        }
        $xpath = new \DOMXpath($this);
        return $xpath->query(CssSelector::toXPath($selector, 'descendant::'), $contextnode);
    }

    [...]

    public function loadHTMLFile($filename, $options = 0) {
        $this->loadHTML(file_get_contents($filename), $options);
    }

    public function loadHTML($source, $options = 0) {
        if ($source && $source != '') {
            $data = trim($source);
            $html5 = new HTML5(array('targetDocument' => $this, 'disableHtmlNsInDom' => true));
            $data_start = mb_substr($data, 0, 10);
            if (strpos($data_start, '<!DOCTYPE ') === 0 || strpos($data_start, '<html>') === 0) {
                $html5->loadHTML($data);
            } else {
                @$this->loadHTML('<!DOCTYPE html><html><head><meta charset="' . $encoding . '" /></head><body></body></html>');
                $t = $html5->loadHTMLFragment($data);
                $docbody = $this->getElementsByTagName('body')->item(0);
                while ($t->hasChildNodes()) {
                    $docbody->appendChild($t->firstChild);
                }
            }
        }
    }

    [...]
}

см. также разбор XML-документов с помощью селекторов CSS в Symfony создатель Фабьен Potencier о своем решении создать компонент CssSelector для Symfony и как ее использовать.


С FluidXML вы можете запросить и повторить XML с помощью XPath-выражения и селекторы CSS.

$doc = fluidxml('<html>...</html>');

$title = $doc->query('//head/title')[0]->nodeValue;

$doc->query('//body/p', 'div.active', '#bgId')
        ->each(function($i, $node) {
            // $node is a DOMNode.
            $tag   = $node->nodeName;
            $text  = $node->nodeValue;
            $class = $node->getAttribute('class');
        });

https://github.com/servo-php/fluidxml


существует несколько причин не анализировать HTML регулярным выражением. Но, если у вас есть полный контроль над тем, что HTML будет сгенерирован, то вы можете сделать с помощью простого регулярного выражения.

выше это функция, которая анализирует HTML регулярным выражением. Обратите внимание, что эта функция очень чувствительна и требует, чтобы HTML подчинялся определенным правилам, но она очень хорошо работает во многих сценариях. Если вы хотите простой парсер и не хотите устанавливать библиотеки, дайте это выстрел:

function array_combine_($keys, $values) {
    $result = array();
    foreach ($keys as $i => $k) {
        $result[$k][] = $values[$i];
    }
    array_walk($result, create_function('&$v', '$v = (count($v) == 1)? array_pop($v): $v;'));

    return $result;
}

function extract_data($str) {
    return (is_array($str))
        ? array_map('extract_data', $str)
        : ((!preg_match_all('#<([A-Za-z0-9_]*)[^>]*>(.*?)</>#s', $str, $matches))
            ? $str
            : array_map(('extract_data'), array_combine_($matches[1], $matches[2])));
}

print_r(extract_data(file_get_contents("http://www.google.com/")));

JSON и массив из XML в трех строках:

$xml = simplexml_load_string($xml_string);
$json = json_encode($xml);
$array = json_decode($json,TRUE);

та-да!


Я создал библиотеку HTML5DOMDocument, которая свободно доступна по адресу https://github.com/ivopetkov/html5-dom-document-php

Он также поддерживает селекторы запросов, которые, я думаю, будут очень полезны в вашем случае. Вот пример кода:

$dom = new IvoPetkov\HTML5DOMDocument();
$dom->loadHTML('<!DOCTYPE html><html><body><h1>Hello</h1><div class="content">This is some text</div></body></html>');
echo $dom->querySelector('h1')->innerHTML;

Если вы знакомы с селектором jQuery, вы можете использовать ScarletsQuery для PHP

<pre><?php
include "ScarletsQuery.php";

// Load the HTML content and parse it
$html = file_get_contents('https://www.lipsum.com');
$dom = Scarlets\Library\MarkupLanguage::parseText($html);

// Select meta tag on the HTML header
$description = $dom->selector('head meta[name="description"]')[0];

// Get 'content' attribute value from meta tag
print_r($description->attr('content'));

$description = $dom->selector('#Content p');

// Get element array
print_r($description->view);

эта библиотека обычно занимает менее 1 секунды для обработки автономного html.
Он также принимает недопустимый HTML или отсутствующую цитату по атрибутам тегов.