Как можно проанализировать HTML / XML и извлечь из него информацию?
Как можно проанализировать HTML / XML и извлечь из него информацию?
Ответы:
Я предпочитаю использовать одно из собственных расширений XML, поскольку они поставляются в комплекте с PHP, обычно работают быстрее всех сторонних библиотек и дают мне полный контроль над разметкой.
Расширение DOM позволяет вам работать с документами XML через API DOM с PHP 5. Это реализация объектной модели документов W3C Core Level 3, независимого от платформы и языка интерфейса, который позволяет программам и сценариям динамически получать доступ и обновлять содержание, структура и стиль документов.
DOM способен анализировать и изменять (неработающий) HTML реального мира и выполнять запросы XPath . Он основан на libxml .
Требуется некоторое время, чтобы стать продуктивным с DOM, но это время того стоит IMO. Поскольку DOM является независимым от языка интерфейсом, вы найдете реализации на многих языках, поэтому, если вам нужно изменить язык программирования, скорее всего, вы уже знаете, как использовать API DOM этого языка.
Базовый пример использования можно найти в Grabbing атрибут href элемента A, а общий концептуальный обзор можно найти в DOMDocument на php
Как использовать расширение DOM широко освещалось в StackOverflow , поэтому, если вы решите его использовать, вы можете быть уверены, что большинство проблем, с которыми вы столкнулись, могут быть решены с помощью поиска / просмотра Переполнения стека.
Расширение XMLReader - это синтаксический анализатор XML. Читатель действует как курсор, идущий вперед по потоку документов и останавливающийся на каждом узле в пути.
XMLReader, как и DOM, основан на libxml. Я не знаю, как вызвать модуль HTML Parser, так что скорее всего, использование XMLReader для анализа неработающего HTML может быть менее надежным, чем использование DOM, где вы можете явно указать ему использовать модуль синтаксического анализа HTML libxml.
Базовый пример использования можно найти при получении всех значений из тегов h1 с использованием php
Это расширение позволяет создавать анализаторы XML, а затем определять обработчики для различных событий XML. Каждый анализатор XML также имеет несколько параметров, которые вы можете настроить.
Библиотека XML Parser также основана на libxml и реализует push-анализатор XML в стиле SAX . Это может быть лучшим выбором для управления памятью, чем DOM или SimpleXML, но с ним будет сложнее работать, чем парсером, реализованным XMLReader.
Расширение SimpleXML предоставляет очень простой и легко используемый набор инструментов для преобразования XML в объект, который может обрабатываться с помощью обычных селекторов свойств и итераторов массива.
SimpleXML - это вариант, когда вы знаете, что HTML является верным XHTML. Если вам нужно разобрать битый HTML, даже не рассматривайте SimpleXml, потому что он захлебнется.
Базовый пример использования можно найти в разделе Простая программа для узла CRUD и значения узла файла XML, а в руководстве по PHP есть множество дополнительных примеров .
Если вы предпочитаете использовать стороннюю библиотеку, я бы предложил использовать библиотеку, которая на самом деле использует DOM / libxml, а не разбор строки.
FluentDOM предоставляет jQuery-подобный свободный XML-интерфейс для DOMDocument в PHP. Селекторы пишутся в XPath или CSS (используя конвертер CSS в XPath). Текущие версии расширяют DOM, реализуя стандартные интерфейсы, и добавляют функции из DOM Living Standard. FluentDOM может загружать форматы, такие как JSON, CSV, JsonML, RabbitFish и другие. Может быть установлен через Composer.
Wa72 \ HtmlPageDom` - это библиотека PHP для простого манипулирования HTML-документами. Для обхода дерева DOM требуется DomCrawler из компонентов Symfony2 и расширяет его, добавляя методы для манипулирования деревом DOM HTML-документов.
phpQuery - это цепочечный API-интерфейс на основе объектной модели документов (DOM), управляемый селектором на стороне сервера, основанный на jQuery JavaScript Library, написанный на PHP5, и обеспечивающий дополнительный интерфейс командной строки (CLI).
Также смотрите: https://github.com/electrolinux/phpquery
Zend_Dom предоставляет инструменты для работы с документами и структурами DOM. В настоящее время мы предлагаем Zend_Dom_Query, который предоставляет унифицированный интерфейс для запросов к документам DOM с использованием селекторов XPath и CSS.
QueryPath - это библиотека PHP для управления XML и HTML. Он предназначен для работы не только с локальными файлами, но и с веб-службами и ресурсами базы данных. Он реализует большую часть интерфейса jQuery (включая селекторы в стиле CSS), но он сильно настроен для использования на стороне сервера. Может быть установлен через Composer.
fDOMDocument расширяет стандартную модель DOM для использования во всех случаях ошибок вместо предупреждений или уведомлений PHP. Они также добавляют различные пользовательские методы и ярлыки для удобства и упрощения использования DOM.
Sabre / xml - это библиотека, которая упаковывает и расширяет классы XMLReader и XMLWriter для создания простой системы отображения «xml to object / array» и шаблона проектирования. Написание и чтение XML является однопроходным, поэтому может быть быстрым и требовать мало памяти для больших XML-файлов.
FluidXML - это PHP-библиотека для управления XML с помощью лаконичного и свободного API. Он использует XPath и гибкий шаблон программирования, чтобы быть веселым и эффективным.
Преимущество использования DOM / libxml состоит в том, что вы получаете хорошую производительность из коробки, потому что вы основаны на собственном расширении. Однако не все сторонние библиотеки идут по этому пути. Некоторые из них перечислены ниже
- Анализатор HTML DOM, написанный на PHP5 +, позволяет очень просто управлять HTML!
- Требуется PHP 5+.
- Поддерживает неверный HTML.
- Найти теги на странице HTML с селекторами, как jQuery.
- Извлечение содержимого из HTML в одну строку.
Я вообще не рекомендую этот парсер. Кодовая база ужасна, а сам парсер довольно медленный и требует много памяти. Не все селекторы jQuery (такие как дочерние селекторы ) возможны. Любая из библиотек на основе libxml должна легко превзойти это.
PHPHtmlParser - это простой, гибкий анализатор HTML, который позволяет вам выбирать теги с помощью любого селектора CSS, например, jQuery. Цель состоит в том, чтобы помочь в разработке инструментов, которые требуют быстрого и простого способа просмотреть html, независимо от того, действителен он или нет! Этот проект изначально поддерживался sunra / php-simple-html-dom-parser, но поддержка, похоже, прекратилась, так что этот проект - моя адаптация его предыдущей работы.
Опять же, я бы не рекомендовал этот парсер. Это довольно медленно с высокой загрузкой процессора. Также нет функции очистки памяти созданных объектов DOM. Эти проблемы особенно характерны для вложенных циклов. Сама документация является неточной и написанной с ошибками, без ответов на исправления с 14 апреля 16.
- Универсальный токенизатор и HTML / XML / RSS DOM Parser
- Возможность манипулировать элементами и их атрибутами
- Поддерживает неверный HTML и UTF8
- Может выполнять расширенные CSS3-подобные запросы к элементам (например, jQuery - поддерживаются пространства имен)
- HTML beautifier (как HTML Tidy)
- Сократить CSS и Javascript
- Сортировка атрибутов, изменение регистра символов, корректный отступ и т. Д.
- растяжимый
- Разбор документов с использованием обратных вызовов на основе текущего символа / токена
- Операции разделены на меньшие функции для легкого переопределения
- Быстро и легко
Никогда не использовал это. Не могу сказать, хорошо ли это.
Вы можете использовать вышеупомянутое для разбора HTML5, но могут быть причуды из-за разметки, которую позволяет HTML5. Так что для HTML5 вы хотите рассмотреть возможность использования выделенного парсера, как
Реализации Python и PHP HTML-парсера на основе спецификации WHATWG HTML5 для максимальной совместимости с основными настольными веб-браузерами.
Мы можем увидеть больше выделенных парсеров после завершения HTML5. Существует также блог от W3 под названием How-To для разбора html 5, который стоит проверить.
Если вам не нравится программировать на PHP, вы также можете использовать веб-сервисы. В общем, я нашел очень мало полезности для них, но это только я и мои варианты использования.
Внешний интерфейс ScraperWiki позволяет извлекать данные в той форме, которую вы хотите использовать в Интернете или в своих собственных приложениях. Вы также можете извлечь информацию о состоянии любого скребка.
Последнее и наименее рекомендуемое , вы можете извлекать данные из HTML с помощью регулярных выражений . В целом, использование регулярных выражений в HTML не рекомендуется.
Большинство фрагментов, которые вы найдете в Интернете для соответствия разметке, являются хрупкими. В большинстве случаев они работают только для очень конкретного фрагмента HTML. Крошечные изменения разметки, такие как добавление пробелов где-либо, добавление или изменение атрибутов в теге, могут привести к сбою RegEx, если он написан неправильно. Вы должны знать, что вы делаете, прежде чем использовать RegEx на HTML.
HTML-парсеры уже знают синтаксические правила HTML. Регулярные выражения должны преподаваться для каждого нового RegEx, который вы пишете. RegEx хороши в некоторых случаях, но это действительно зависит от вашего варианта использования.
Вы можете написать более надежные парсеры , но написание полноценного и надежного пользовательского парсера с регулярными выражениями - пустая трата времени, когда вышеупомянутые библиотеки уже существуют и справляются с этим гораздо лучше.
Также см. Разбор HTML Путь Ктулху
Если вы хотите потратить немного денег, посмотрите на
Я не связан с PHP Architect или авторами.
Попробуйте простой HTML DOM Parser
// 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>';
// 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;
// Dump contents (without tags) from HTML
echo file_get_html('http://www.google.com/')->plaintext;
// Create DOM from URL
$html = file_get_html('http://slashdot.org/');
// Find all article blocks
foreach($html->find('div.article') as $article) {
$item['title'] = $article->find('div.title', 0)->plaintext;
$item['intro'] = $article->find('div.intro', 0)->plaintext;
$item['details'] = $article->find('div.details', 0)->plaintext;
$articles[] = $item;
}
print_r($articles);
Просто используйте DOMDocument-> loadHTML () и покончите с этим. Алгоритм синтаксического анализа HTML в libxml достаточно хорош и быстр, и, вопреки распространенному мнению, не подавляет искаженный HTML.
Почему вы не должны и когда вы должны использовать регулярные выражения?
Во-первых, распространенное заблуждение: регулярные выражения не предназначены для « разбора » HTML. Однако регулярные выражения могут « извлечь » данные. Извлечение - это то, для чего они созданы. Основным недостатком регулярного извлечения HTML-кода над надлежащими наборами инструментов SGML или базовыми синтаксическими анализаторами XML являются их синтаксические усилия и разная надежность.
Учтите, что создание надежного регулярного выражения для извлечения HTML:
<a\s+class="?playbutton\d?[^>]+id="(\d+)".+? <a\s+class="[\w\s]*title
[\w\s]*"[^>]+href="(http://[^">]+)"[^>]*>([^<>]+)</a>.+?
является менее читабельным, чем простой эквивалент phpQuery или QueryPath:
$div->find(".stationcool a")->attr("title");
Однако существуют конкретные случаи использования, в которых они могут помочь.
<!--
, которые, тем не менее, иногда являются более полезными якорями для извлечения. В частности, вариации псевдо-HTML <$var>
или остатки SGML легко укротить с помощью регулярных выражений.Иногда даже рекомендуется предварительно извлечь фрагмент HTML с помощью регулярных выражений /<!--CONTENT-->(.+?)<!--END-->/
и обработать остаток с помощью более простых внешних интерфейсов анализатора HTML.
Примечание: у меня действительно есть это приложение , где я использую разбор XML и регулярные выражения в качестве альтернативы. Буквально на прошлой неделе перестал разбираться PyQuery, и регулярное выражение все еще работало. Да, странно, и я не могу объяснить это сам. Но так случилось.
Поэтому, пожалуйста, не отказывайтесь от реальных соображений, просто потому, что они не соответствуют регулярному выражению = злой мем. Но давайте также не будем голосовать слишком много. Это просто sidenote для этой темы.
DOMComment
Можно читать комментарии, поэтому нет причин использовать Regex для этого.
DOM
использует libxml, а libxml имеет отдельный модуль синтаксического анализа HTML, который будет использоваться при загрузке HTML, loadHTML()
чтобы он мог очень сильно загружать «реальный» (читай неработающий) HTML.
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 также позволяет вставлять новые теги в stream ( ->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")
Simple HTML DOM - отличный анализатор с открытым исходным кодом:
Он обрабатывает элементы DOM объектно-ориентированным способом, и новая итерация имеет большой охват для несовместимого кода. Есть также несколько замечательных функций, которые вы могли бы видеть в JavaScript, например, функция «find», которая будет возвращать все экземпляры элементов этого имени тега.
Я использовал это во многих инструментах, тестируя на многих различных типах веб-страниц, и я думаю, что это прекрасно работает.
Один общий подход, о котором я не упомянул, это запуск HTML через Tidy. , который можно настроить так, чтобы он выдавал гарантированно-действительный XHTML. Тогда вы можете использовать любую старую библиотеку XML.
Но в зависимости от вашей конкретной проблемы вы должны взглянуть на этот проект: http://fivefilters.org/content-only/ - это модифицированная версия алгоритма Readability , который предназначен для извлечения только текстового содержимого (не заголовков) и нижние колонтитулы) со страницы.
За 1а и 2: я бы проголосовал за новый класс компонентов Symfony DOMCrawler ( DomCrawler ). Этот класс позволяет выполнять запросы, аналогичные селекторам CSS. Взгляните на эту презентацию для примеров из реального мира: news-of-the-symfony2-world .
Компонент предназначен для автономной работы и может использоваться без Symfony.
Единственным недостатком является то, что он будет работать только с PHP 5.3 или новее.
Кстати, это обычно называется скребком экрана . Для этого я использовал библиотеку Simple HTML Dom Parser .
Мы создали довольно много сканеров для наших нужд. В конце концов, лучше всего использовать простые регулярные выражения. Несмотря на то, что перечисленные выше библиотеки хороши по той причине, что они созданы, если вы знаете, что ищете, регулярные выражения - более безопасный путь, поскольку вы можете обрабатывать также недопустимые структуры HTML / XHTML , которые потерпят неудачу при загрузке через большинство парсеров.
Я рекомендую PHP Simple 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 вместо анализа строк: phpQuery , Zend_Dom , QueryPath и FluentDom .
Да, вы можете использовать simple_html_dom для этой цели. Тем не менее, я довольно много работал с simple_html_dom, особенно для удаления из Интернета, и обнаружил, что он слишком уязвим. Это делает основную работу, но я не буду рекомендовать это так или иначе.
Я никогда не использовал curl для этой цели, но я узнал, что curl может выполнять эту работу гораздо эффективнее и гораздо надежнее.
Пожалуйста, проверьте эту ссылку: scraping-sites-with-curl
QueryPath хорош, но будьте осторожны с «состоянием отслеживания», потому что если вы не понимаете, что это значит, это может означать, что вы тратите много времени на отладку, пытаясь выяснить, что произошло и почему код не работает.
Это означает, что каждый вызов в наборе результатов изменяет набор результатов в объекте, он не является цепным, как в jquery, где каждая ссылка является новым набором, у вас есть один набор, который является результатом вашего запроса, и каждый вызов функции изменяет этот единственный набор.
чтобы получить jquery-подобное поведение, вам нужно выполнить ветвление, прежде чем выполнять операцию, подобную фильтрующему / модифицирующему, это означает, что она будет более точно отражать то, что происходит в jquery.
$results = qp("div p");
$forename = $results->find("input[name='forename']");
$results
теперь содержит результирующий набор для input[name='forename']
НЕ исходного запроса, "div p"
это меня сильно смутило , я обнаружил, что QueryPath отслеживает фильтры и находит и все, что изменяет ваши результаты и сохраняет их в объекте. вам нужно сделать это вместо
$forename = $results->branch()->find("input[name='forname']")
тогда $results
он не будет изменен, и вы сможете снова и снова использовать результирующий набор, возможно, кто-то, обладающий гораздо большими знаниями, может немного прояснить ситуацию, но в основном это похоже на то, что я нашел.
Advanced Html Dom - это простая замена HTML DOM , предлагающая тот же интерфейс, но основанный на DOM, что означает отсутствие проблем с памятью.
Он также имеет полную поддержку CSS, включая расширения jQuery .
Для HTML5 библиотека html5 была заброшена в течение многих лет. Единственная библиотека HTML5, которую я могу найти с недавними обновлениями и записями об обслуживании, - это html5-php, который только что был переведен в бета-версию 1.0 чуть более недели назад.
Я написал анализатор XML общего назначения, который может легко обрабатывать файлы GB. Он основан на XMLReader и очень прост в использовании:
$source = new XmlExtractor("path/to/tag", "/path/to/file.xml");
foreach ($source as $tag) {
echo $tag->field1;
echo $tag->field2->subfield1;
}
Я создал библиотеку с именем 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>');
[...]
Библиотека также включает собственный автозагрузчик нулевой конфигурации для PSR-0-совместимых библиотек. Приведенный пример должен работать из коробки без какой-либо дополнительной настройки. Кроме того, вы можете использовать его с композитором.
XML_HTMLSax
довольно стабилен - даже если он больше не поддерживается. Другой вариант может состоять в том, чтобы передать вам HTML через HTML Tidy, а затем проанализировать его с помощью стандартных инструментов XML.
Есть много способов обработки HTML / XML DOM, большинство из которых уже были упомянуты. Следовательно, я не буду пытаться перечислить их сам.
Я просто хочу добавить, что лично я предпочитаю использовать расширение DOM и почему:
И хотя мне не хватает возможности использовать селекторы CSS для DOMDocument
, есть довольно простой и удобный способ добавить эту функцию: создание подклассов DOMDocument
и добавление JS-подобныхquerySelectorAll
и querySelector
методов к вашему подклассу.
Для анализа селекторов я рекомендую использовать очень минималистичный компонент CssSelector из среды Symfony. . Этот компонент просто переводит селекторы CSS в селекторы XPath, которые затем могут быть переданы в a 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 и способы его использования.
С FluidXML вы можете запрашивать и выполнять итерацию XML, используя XPath и CSS Selector .
$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');
});
JSON и массив из XML в три строки:
$xml = simplexml_load_string($xml_string);
$json = json_encode($xml);
$array = json_decode($json,TRUE);
Та да!
Есть несколько причин не разбирать 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/")));
Я создал библиотеку под названием HTML5DOMDocument, которая свободно доступна по адресу https://github.com/ivopetkov/html5-dom-document-php.
Он также поддерживает селекторы запросов, которые, я думаю, будут чрезвычайно полезны в вашем случае. Вот пример кода:
$dom = new IvoPetkov\HTML5DOMDocument();
$dom->loadHTML('<!DOCTYPE html><html><body><h1>Hello</h1><div class="content">This is some text</div></body></html>');
echo $dom->querySelector('h1')->innerHTML;
Если вы знакомы с селектором jQuery, вы можете использовать ScarletsQuery для PHP
<pre><?php
include "ScarletsQuery.php";
// Load the HTML content and parse it
$html = file_get_contents('https://www.lipsum.com');
$dom = Scarlets\Library\MarkupLanguage::parseText($html);
// Select meta tag on the HTML header
$description = $dom->selector('head meta[name="description"]')[0];
// Get 'content' attribute value from meta tag
print_r($description->attr('content'));
$description = $dom->selector('#Content p');
// Get element array
print_r($description->view);
Эта библиотека обычно занимает менее 1 секунды для обработки офлайн html.
Он также принимает неверный HTML или пропущенную кавычку в атрибутах тега.
Лучший метод для разбора 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;
}