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

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

+2024
источник поделиться
30 ответов

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

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

DOM

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

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

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

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

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

XMLReader

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

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

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

XML Parser

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

Библиотека XML Parser также основана на libxml и реализует push-анализатор XML в стиле SAX. Это может быть лучшим выбором для управления памятью, чем DOM или SimpleXML, но с ним будет сложнее работать, чем с парсером, реализованным XMLReader.

SimpleXml

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

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

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


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

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

FluentDom - Репо

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

HtmlPageDom

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

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

phpQuery - это цепочечный API-интерфейс на основе объектной модели документов (DOM), управляемый селектором на стороне сервера, основанный на jQuery JavaScript Library, написанный на 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.

сабля /XML

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

FluidXML

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


Сторонний (не на основе libxml)

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

PHP Простой HTML DOM Parser

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

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

PHP Html Parser

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

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

Ganon

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

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


HTML 5

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

html5lib

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

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


WebServices

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

ScraperWiki.

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


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

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

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

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

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

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


книги

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

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

+1827
источник

Попробуйте Простой HTML DOM Parser

  • Парсер 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);
+317
источник

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

+231
источник

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

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

Считаем, что создание несколько надежного HTML-выражения regex:

<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-объекты часто требуют ручного ухода.
  • И, наконец, для чрезвычайно простых задач, таких как extracting < img src= urls, они на самом деле являются вероятным инструментом. Преимущество в скорости по сравнению с синтаксическими анализаторами SGML/XML в основном просто предназначено для этих основных процедур извлечения.

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

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

+143
источник

phpQuery и QueryPath чрезвычайно аналогично воспроизведению свободного API jQuery. Вот почему они - два из самых простых подходов к правильному анализу 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 (из-за меньшего количества общих функций).

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

И здесь всеобъемлющее введение QueryPath.

<сильные > Преимущества

  • Простота и надежность
  • Простые в использовании альтернативы ->find("a img, a object, div a")
  • Надлежащее удаление данных (по сравнению с регулярным выражением grepping)
+129
источник

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

simplehtmldom.sourceforge

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

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

+88
источник

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

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

+59
источник

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

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

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

+55
источник

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

+52
источник

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

+41
источник

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

У него действительно есть приятные функции, например:

foreach($html->find('img') as $element)
       echo $element->src . '<br>';
+38
источник

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

+36
источник

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

+29
источник

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

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

Просьба ознакомиться с этой ссылкой: scraping-websites-with-curl

+24
источник

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

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

чтобы получить jquery-подобное поведение, вам нужно отделить его до того, как вы выполните операцию filter/modify like, что означает, что он будет более точно отражать то, что происходит в 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']")

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

+23
источник

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

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

+19
источник

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

+18
источник

Я написал анализатор 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 repo: XmlExtractor

+17
источник

Я создал библиотеку с именем 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 footer
$sitefooter = $body->select('.site-footer > .site-center');

// Set some attributes for the site 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 footer
$sitefooterparent = $sitefooter->parent();

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

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

[...]

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


  • Переименовано 'select', по понятным причинам
  • Переименовано 'void', так как 'empty' является зарезервированным словом в PHP

ПРИМЕЧАНИЕ:

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

+17
источник

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

+15
источник

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

+15
источник

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

+12
источник

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

+11
источник

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

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

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

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

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

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

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

Для разбора 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 и как его использовать.

+11
источник

С 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

+9
источник

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

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

Ta da!

+7
источник

Существует несколько причин не анализировать 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_]*)[^>]*>(.*?)</\1>#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/")));
+7
источник

Я создал библиотеку под названием 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;
+2
источник

Если вы знакомы с селектором 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 или отсутствующую цитату в атрибутах тегов.

0
источник

Лучший метод для разбора xml:

$xml='http://www.example.com/rss.xml';
$rss = simplexml_load_string($xml);
$i = 0;
foreach ($rss->channel->item as $feedItem) {
$i++;
echo $title=$feedItem->title;
echo '<br>';
echo $link=$feedItem->link;
echo '<br>';
if($feedItem->description !='') {$des=$feedItem->description;} else {$des='';}
echo $des;
echo '<br>';
if($i>5) break;
}
0
источник

Посмотрите другие вопросы по меткам или Задайте вопрос