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

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

1936
задан RobertPitt 26 авг. '10 в 20:17
источник поделиться
29 ответов

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

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

DOM

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

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

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

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

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

XMLReader

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

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

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

XML Parser

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

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

SimpleXml

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

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

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


Библиотеки сторонних организаций (основанные на libxml)

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

FluentDom

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

HtmlPageDom

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

phpQuery (не обновляется в течение многих лет)

phpQuery - это серверный, цельный, CSS3-селекторный API-интерфейс Document Object Model (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.

saber/xml

saber/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 - namespaces)
  • Декодер HTML (например, HTML Tidy)
    • Минимизировать CSS и Javascript
    • Сортировка атрибутов, изменение символа, правильный отступ и т.д.
  • Extensible
    • Анализ документов с использованием обратных вызовов на основе текущего символа/токена
    • Операции, разделенные меньшими функциями для легкого переопределения
  • Быстрый и простой

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


HTML 5

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

html5lib

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

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


WebServices

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

YQL

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

ScraperWiki.

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


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

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

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

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

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

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


Книги

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

Я не являюсь аффилированным лицом с PHP Architect или авторами.

1756
ответ дан Gordon 26 авг. '10 в 20:19
источник поделиться

Попробуйте Простой 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);
312
ответ дан Naveed 26 авг. '10 в 20:18
источник поделиться

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

225
ответ дан Edward Z. Yang 26 нояб. '08 в 23:02
источник поделиться

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

Во-первых, распространенное неправильное выражение: регулярные выражения не предназначены для " синтаксического анализа" 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. Но пусть тоже не проголосует слишком много. Это просто сидение для этой темы.

139
ответ дан mario 06 сент. '10 в 12:40
источник поделиться

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)
127
ответ дан mario 07 сент. '10 в 17:45
источник поделиться

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

simplehtmldom.sourceforge

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

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

85
ответ дан Robert Elwell 16 нояб. '08 в 1:16
источник поделиться

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

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

58
ответ дан Eli 01 мая '11 в 5:04
источник поделиться

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

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

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

54
ответ дан Timo 06 сент. '10 в 12:19
источник поделиться

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

51
ответ дан Joel Verhagen 26 авг. '10 в 20:20
источник поделиться

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

40
ответ дан jancha 04 окт. '11 в 16:14
источник поделиться

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

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

foreach($html->find('img') as $element)
       echo $element->src . '<br>';
37
ответ дан Greg 07 нояб. '12 в 0:02
источник поделиться

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

35
ответ дан Jens 14 апр. '11 в 22:08
источник поделиться

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

28
ответ дан danidacar 07 сент. '10 в 11:57
источник поделиться

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

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

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

22
ответ дан Rafay 05 янв. '12 в 17:49
источник поделиться

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 не будет изменен, и вы можете повторно использовать результирующий набор снова и снова, возможно, кто-то, у кого гораздо больше знаний, может немного его очистить, но в основном это похоже на то, что я нашел.

22
ответ дан Christopher Thomas 15 апр. '12 в 16:12
источник поделиться

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

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

18
ответ дан pguardiario 18 дек. '14 в 7:29
источник поделиться

Я создал библиотеку с именем 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
ответ дан John Slegers 09 июля '15 в 17:33
источник поделиться

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

16
ответ дан Reid Johnson 08 июля '13 в 21:50
источник поделиться

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

16
ответ дан Paul Warelis 12 мая '13 в 4:23
источник поделиться

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

14
ответ дан CesarB 16 нояб. '08 в 1:24
источник поделиться

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

13
ответ дан Richard Le Poidevin 31 мая '11 в 18:12
источник поделиться

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

11
ответ дан Tuong Le 29 дек. '12 в 13:07
источник поделиться

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

11
ответ дан troelskn 15 нояб. '08 в 22:55
источник поделиться

Существует много способов обработки 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 и как его использовать.

10
ответ дан John Slegers 03 июля '14 в 12:55
источник поделиться

С 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
ответ дан Daniele Orlando 11 дек. '15 в 6:51
источник поделиться

Существует несколько причин не анализировать 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
ответ дан Daniel Loureiro 05 дек. '13 в 16:05
источник поделиться

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

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

Ta da!

6
ответ дан Antonio Max 16 окт. '13 в 0:35
источник поделиться

Я создал библиотеку под названием 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
ответ дан Ivo Petkov 21 дек. '17 в 11:38
источник поделиться

Если вы знакомы с селектором 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
ответ дан StefansArya 16 авг. '18 в 15:35
источник поделиться

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