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

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

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

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

DOM

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

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

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

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

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

XMLReader

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

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

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

XML Parser

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

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

SimpleXml

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

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

Пример базового использования можно найти в простой программе для узлов CRUD и значений узлов 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.

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

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


HTML 5

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

html5lib

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

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


WebServices

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

YQL

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

ScraperWiki .

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


Обычные выражения

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

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

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

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

См. Также Parsing Html The Cthulhu Way


книги

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

  • Руководство PHP-архитектора по веб-оккупированию с помощью PHP

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

Попробуйте простой 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); 

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

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

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

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

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

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)

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

simplehtmldom.sourceforge

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

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

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

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

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

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

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

Между прочим, это часто называют скрипинг экрана . Библиотека, которую я использовал для этого, – это Simple HTML Dom Parser .

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

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

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

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

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

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

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

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

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

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']") 

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

Я написал 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.

Я создал библиотеку с именем 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>'); [...] 

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

  • [x] $ (1)
  • [x] $ .parseHTML
  • [x] $ .parseXML
  • [x] $ .parseJSON
  • [x] $ selection.add
  • [x] $ selection.addClass
  • [x] $ selection.after
  • [x] $ selection.append
  • [x] $ selection.attr
  • [x] $ selection.before
  • [x] $ selection.children
  • [x] $ selection.closest
  • [x] $ selection.contents
  • [x] $ selection.detach
  • [x] $ selection.each
  • [x] $ selection.eq
  • [x] $ selection.empty (2)
  • [x] $ selection.find
  • [x] $ selection.first
  • [x] $ selection.get
  • [x] $ selection.insertAfter
  • [x] $ selection.insertBefore
  • [x] $ selection.last
  • [x] $ selection.parent
  • [x] $ selection.parents
  • [x] $ selection.remove
  • [x] $ selection.removeAttr
  • [x] $ selection.removeClass
  • [x] $ selection.text
  • [x] $ selection.wrap

  1. Переименовано 'select', по понятным причинам
  2. Переименовано «void», поскольку «empty» является зарезервированным словом в PHP

ЗАМЕТКА :

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

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

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

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

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

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

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

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

Для синтаксического анализа селекторов я рекомендую использовать минималистичный компонент CssSelector из структуры Symfony . Этот компонент просто переводит селектора CSS в селектора XPath, которые затем могут быть DOMXpath в 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 Fabien Potencier по его решению создать компонент CssSelector для Symfony и как его использовать.

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

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

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

 $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_]*)[^>]*>(.*?)</\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/"))); 

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;