Как вы парсите и обрабатываете HTML/CSS с PHP?
Как можно проанализировать HTML/XML и извлечь из него информацию?
31 ответ
Собственные расширения XML
Я предпочитаю использовать одно из собственных расширений XML, поскольку они поставляются в комплекте с PHP, обычно работают быстрее, чем все сторонние библиотеки, и дают мне полный контроль над разметкой.
DOM
Расширение DOM позволяет вам работать с XML-документами через DOM API с PHP 5. Это реализация объектной модели документов W3C Core Level 3, независимого от платформы и языка интерфейса, который позволяет программам и сценариям динамически получать доступ и обновлять содержание, структура и стиль документов.
DOM способен анализировать и изменять (неработающий) HTML реального мира и выполнять запросы XPath. Он основан на libxml.
Требуется некоторое время, чтобы стать продуктивным с DOM, но это время того стоит IMO. Поскольку DOM является независимым от языка интерфейсом, вы найдете реализации на многих языках, поэтому, если вам нужно изменить язык программирования, скорее всего, вы уже знаете, как использовать API DOM этого языка.
Базовый пример использования можно найти в Схватке атрибута href элемента A, а общий концептуальный обзор можно найти в DOMDocument на php.
Как использовать расширение DOM широко освещалось в Stackru, поэтому, если вы решите его использовать, вы можете быть уверены, что большинство проблем, с которыми вы столкнулись, могут быть решены с помощью поиска / просмотра Переполнения стека.
XMLReader
Расширение XMLReader - это синтаксический анализатор XML. Читатель действует как курсор, идущий вперед по потоку документов и останавливающийся на каждом узле в пути.
XMLReader, как и DOM, основан на libxml. Я не знаю, как вызвать модуль HTML Parser, так что скорее всего, использование XMLReader для анализа неработающего HTML может быть менее надежным, чем использование DOM, где вы можете явно указать ему использовать модуль синтаксического анализа HTML libxml.
Базовый пример использования можно найти при получении всех значений из тегов h1 с использованием php
XML Parser
Это расширение позволяет создавать анализаторы XML, а затем определять обработчики для различных событий XML. Каждый анализатор XML также имеет несколько параметров, которые вы можете настроить.
Библиотека XML Parser также основана на libxml и реализует push-анализатор XML в стиле SAX. Это может быть лучшим выбором для управления памятью, чем DOM или SimpleXML, но с ним будет сложнее работать, чем с парсером, реализованным XMLReader.
SimpleXml
Расширение SimpleXML предоставляет очень простой и легко используемый набор инструментов для преобразования XML в объект, который может обрабатываться с помощью обычных селекторов свойств и итераторов массива.
SimpleXML - это вариант, когда вы знаете, что HTML является верным XHTML. Если вам нужно разобрать битый HTML, даже не рассматривайте SimpleXml, потому что он захлебнется.
Базовый пример использования можно найти в разделе Простая программа для узла CRUD и значения узла файла XML, и в руководстве по PHP есть множество дополнительных примеров.
Сторонние библиотеки (на основе libxml)
Если вы предпочитаете использовать стороннюю библиотеку, я бы предложил использовать библиотеку, которая на самом деле использует DOM / libxml, а не разбор строки.
FluentDom - Репо
FluentDOM предоставляет jQuery-подобный свободный XML-интерфейс для DOMDocument в PHP. Селекторы пишутся в XPath или CSS (используя конвертер CSS в XPath). Текущие версии расширяют DOM, реализуя стандартные интерфейсы, и добавляют функции из DOM Living Standard. FluentDOM может загружать форматы, такие как JSON, CSV, JsonML, RabbitFish и другие. Может быть установлен через Composer.
HtmlPageDom
Wa72 \ HtmlPageDom` - это библиотека PHP для простого манипулирования HTML-документами. Для обхода дерева DOM требуется DomCrawler из компонентов Symfony2 и расширяет его, добавляя методы для манипулирования деревом DOM HTML-документов.
phpQuery (не обновляется годами)
phpQuery - это цепочечный API-интерфейс на основе объектной модели документов (DOM), управляемый селектором на стороне сервера, основанный на jQuery JavaScript Library, написанный на PHP5, и обеспечивающий дополнительный интерфейс командной строки (CLI).
Также смотрите: https://github.com/electrolinux/phpquery
Zend_Dom
Zend_Dom предоставляет инструменты для работы с документами и структурами DOM. В настоящее время мы предлагаем Zend_Dom_Query, который предоставляет унифицированный интерфейс для запросов к документам DOM с использованием селекторов XPath и CSS.
QueryPath
QueryPath - это библиотека PHP для управления XML и HTML. Он предназначен для работы не только с локальными файлами, но и с веб-службами и ресурсами базы данных. Он реализует большую часть интерфейса jQuery (включая селекторы в стиле CSS), но он сильно настроен для использования на стороне сервера. Может быть установлен через Composer.
fDOMDocument
fDOMDocument расширяет стандартную модель DOM для использования во всех случаях ошибок вместо предупреждений или уведомлений PHP. Они также добавляют различные пользовательские методы и ярлыки для удобства и упрощения использования DOM.
сабля / XML
Sabre/xml - это библиотека, которая упаковывает и расширяет классы XMLReader и XMLWriter для создания простой системы отображения "xml to object/array" и шаблона проектирования. Написание и чтение XML является однопроходным, поэтому может быть быстрым и требовать мало памяти для больших XML-файлов.
FluidXML
FluidXML - это библиотека PHP для манипулирования XML с помощью лаконичного и свободного API. Он использует XPath и гибкий шаблон программирования, чтобы быть веселым и эффективным.
Сторонний (не на основе libxml)
Преимущество использования DOM/libxml состоит в том, что вы получаете хорошую производительность из коробки, потому что вы основаны на собственном расширении. Однако не все сторонние библиотеки идут по этому пути. Некоторые из них перечислены ниже
PHP Простой HTML DOM Parser
- Анализатор HTML DOM, написанный на PHP5+, позволяет очень просто управлять HTML!
- Требуется PHP 5+.
- Поддерживает неверный HTML.
- Найти теги на странице HTML с селекторами, как jQuery.
- Извлечение содержимого из HTML в одну строку.
Я вообще не рекомендую этот парсер. Кодовая база ужасна, а сам парсер довольно медленный и требует много памяти. Не все селекторы jQuery (такие как дочерние селекторы) возможны. Любая из библиотек на основе libxml должна легко превзойти это.
PHP Html Parser
PHPHtmlParser - это простой, гибкий анализатор html, который позволяет вам выбирать теги с помощью любого селектора CSS, например, jQuery. Цель состоит в том, чтобы помочь в разработке инструментов, которые требуют быстрого и простого способа просмотреть html, независимо от того, действителен он или нет! Этот проект изначально поддерживался sunra / php-simple-html-dom-parser, но поддержка, похоже, прекратилась, так что этот проект - моя адаптация его предыдущей работы.
Опять же, я бы не рекомендовал этот парсер. Это довольно медленно с высокой загрузкой процессора. Также нет функции очистки памяти созданных объектов DOM. Эти проблемы особенно характерны для вложенных циклов. Сама документация неточна и написана с ошибками, без ответов на исправления с 14 апреля 16.
Ganon
- Универсальный токенизатор и HTML/XML/RSS DOM Parser
- Возможность манипулировать элементами и их атрибутами
- Поддерживает неверный HTML и UTF8
- Может выполнять расширенные CSS3-подобные запросы к элементам (например, jQuery - поддерживаются пространства имен)
- HTML beautifier (как HTML Tidy)
- Минимизировать CSS и Javascript
- Сортировать атрибуты, изменить регистр символов, исправить отступы и т. Д.
- растяжимый
- Разбор документов с использованием обратных вызовов на основе текущего символа / токена
- Операции разделены на меньшие функции для легкого переопределения
- Быстро и легко
Никогда не использовал это. Не могу сказать, хорошо ли это.
HTML 5
Вы можете использовать вышеупомянутое для разбора HTML5, но могут быть причуды из-за разметки, которую позволяет HTML5. Так что для HTML5 вы хотите рассмотреть возможность использования выделенного парсера, как
Реализации Python и PHP анализатора HTML на основе спецификации WHATWG HTML5 для максимальной совместимости с основными настольными веб-браузерами.
Мы можем увидеть больше выделенных парсеров после завершения HTML5. Существует также блог от W3 под названием How-To для разбора html 5, который стоит проверить.
WebServices
Если вам не нравится программировать на PHP, вы также можете использовать веб-сервисы. В общем, я нашел очень мало полезности для них, но это только я и мои варианты использования.
ScraperWiki.
Внешний интерфейс ScraperWiki позволяет извлекать данные в той форме, которую вы хотите использовать в Интернете или в своих собственных приложениях. Вы также можете извлечь информацию о состоянии любого скребка.
Регулярные выражения
Последнее и наименее рекомендуемое, вы можете извлекать данные из HTML с помощью регулярных выражений. В целом, использование регулярных выражений в HTML не рекомендуется.
Большинство фрагментов, которые вы найдете в Интернете для соответствия разметке, являются хрупкими. В большинстве случаев они работают только для очень конкретного фрагмента HTML. Крошечные изменения разметки, такие как добавление пробелов где-либо, добавление или изменение атрибутов в теге, могут привести к сбою RegEx, если он написан неправильно. Вы должны знать, что вы делаете, прежде чем использовать RegEx на HTML.
HTML-парсеры уже знают синтаксические правила HTML. Регулярные выражения должны преподаваться для каждого нового RegEx, который вы пишете. RegEx хороши в некоторых случаях, но это действительно зависит от вашего варианта использования.
Вы можете написать более надежные парсеры, но написание полноценного и надежного пользовательского парсера с регулярными выражениями - пустая трата времени, когда вышеупомянутые библиотеки уже существуют и справляются с этим гораздо лучше.
Также см. Разбор HTML Путь Ктулху
книги
Если вы хотите потратить немного денег, посмотрите на
Я не связан с PHP Architect или авторами.
Попробуйте простой 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() и покончите с этим. Алгоритм разбора 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");
Однако есть конкретные случаи использования, в которых они могут помочь.
- Многие внешние интерфейсы DOM не отображают комментарии HTML
<!--
которые, однако, иногда являются более полезными якорями для извлечения. В частности, псевдо-HTML вариации<$var>
или остатки SGML легко укротить с помощью регулярных выражений. - Часто регулярные выражения могут сохранить пост-обработку. Однако сущности HTML часто требуют ручной заботы.
- И, наконец, для чрезвычайно простых задач, таких как извлечение
Иногда даже желательно предварительно извлечь фрагмент HTML с помощью регулярных выражений /<!--CONTENT-->(.+?)<!--END-->/
и обработать остаток, используя более простые интерфейсы HTML-анализатора.
Примечание: у меня действительно есть это приложение, где я использую разбор XML и регулярные выражения в качестве альтернативы. Буквально на прошлой неделе парсинг PyQuery прервался, и регулярное выражение все еще работало. Да, странно, и я не могу объяснить это сам. Но так случилось.
Поэтому, пожалуйста, не отказывайтесь от реальных соображений, просто потому, что они не соответствуют регулярному выражению = злой мем. Но давайте также не будем голосовать слишком много. Это просто sidenote для этой темы.
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")
- Правильное удаление данных (по сравнению с регулярными выражениями)
Simple HTML DOM - отличный анализатор с открытым исходным кодом:
http://simplehtmldom.sourceforge.net/
Он обрабатывает элементы DOM объектно-ориентированным способом, и новая итерация имеет большой охват для несовместимого кода. Есть также несколько замечательных функций, которые вы могли бы видеть в JavaScript, например, функция "find", которая будет возвращать все экземпляры элементов этого имени тега.
Я использовал это во многих инструментах, тестируя на многих различных типах веб-страниц, и я думаю, что это прекрасно работает.
Один общий подход, о котором я не упомянул, - это запуск HTML через Tidy, который можно настроить так, чтобы он выдавал гарантированно действительный XHTML. Тогда вы можете использовать любую старую библиотеку XML.
Но если вам нужна конкретная проблема, вы должны взглянуть на этот проект: http://fivefilters.org/content-only/ - это модифицированная версия алгоритма Readability, который предназначен для извлечения только текстового содержимого (не заголовков). и нижние колонтитулы) со страницы.
За 1а и 2: я бы проголосовал за новый класс компонентов Symfony DOMCrawler ( DomCrawler). Этот класс позволяет выполнять запросы, аналогичные селекторам CSS. Взгляните на эту презентацию для примеров из реального мира: http://www.slideshare.net/fabpot/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.
Да, вы можете использовать simple_html_dom для этой цели. Тем не менее, я довольно много работал с simple_html_dom, особенно для удаления из Интернета, и обнаружил, что он слишком уязвим. Это делает основную работу, но я не буду рекомендовать это так или иначе.
Я никогда не использовал curl для этой цели, но я узнал, что curl может выполнять работу намного эффективнее и гораздо более надежно.
Пожалуйста, проверьте эту ссылку: scraping-sites-with-curl
Advanced Html Dom - это простая замена HTML DOM, предлагающая тот же интерфейс, но основанный на DOM, что означает отсутствие проблем с памятью.
Он также имеет полную поддержку CSS, включая расширения jQuery.
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
не будет изменен, и вы можете использовать набор результатов снова и снова, возможно, кто-то с гораздо большими знаниями может немного прояснить это, но это в основном так из того, что я нашел.
Я создал библиотеку с именем https://github.com/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
- Переименован в "выбрать", по понятным причинам
- Переименован в "void", так как "пустой" является зарезервированным словом в PHP
НОТА:
Библиотека также включает собственный автозагрузчик нулевой конфигурации для PSR-0-совместимых библиотек. Приведенный пример должен работать из коробки без какой-либо дополнительной настройки. Кроме того, вы можете использовать его с композитором.
Вы можете попробовать использовать что-то вроде HTML Tidy для очистки любого "сломанного" HTML и преобразования HTML в XHTML, который затем можно проанализировать с помощью синтаксического анализатора XML.
Я написал анализатор XML общего назначения, который может легко обрабатывать файлы GB. Он основан на XMLReader и очень прост в использовании:
$source = new XmlExtractor("path/to/tag", "/path/to/file.xml");
foreach ($source as $tag) {
echo $tag->field1;
echo $tag->field2->subfield1;
}
XML_HTMLSax
довольно стабилен - даже если он больше не поддерживается. Другой вариант может состоять в том, чтобы передать вам HTML через HTML Tidy, а затем проанализировать его с помощью стандартных инструментов XML.
Есть много способов обработки HTML/XML DOM, большинство из которых уже упоминалось. Следовательно, я не буду пытаться перечислить их сам.
Я просто хочу добавить, что лично я предпочитаю использовать расширение DOM и почему:
- iit оптимально использует преимущество в производительности базового кода C
- это OO PHP (и позволяет мне его подкласс)
- это довольно низкий уровень (что позволяет мне использовать его как не раздутую основу для более продвинутого поведения)
- он обеспечивает доступ к каждой части DOM (в отличие, например, от SimpleXml, который игнорирует некоторые из менее известных функций XML)
- у него есть синтаксис, используемый для сканирования DOM, который похож на синтаксис, используемый в нативном Javascript.
И пока я скучаю по возможности использовать селекторы CSS для DOMDocument
Существует довольно простой и удобный способ добавить эту функцию: создание подклассов DOMDocument
и добавление JS-как querySelectorAll
а также querySelector
методы для вашего подкласса.
Для разбора селекторов я рекомендую использовать очень минималистичный компонент CssSelector из среды Symfony. Этот компонент просто переводит селекторы CSS в селекторы XPath, которые затем могут быть переданы в DOMXpath
получить соответствующий список узлов.
Затем вы можете использовать этот (все еще очень низкоуровневый) подкласс в качестве основы для более высокоуровневых классов, например. анализировать очень специфические типы 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');
});
Есть несколько причин не разбирать 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;
Лучший метод для разбора 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;
}
Есть много способов:
В основном:
Собственные расширения XML: они поставляются в комплекте с PHP, обычно быстрее, чем все сторонние библиотеки, и дают мне весь необходимый вам контроль над разметкой.
DOM: DOM может анализировать и изменять реальный (сломанный) HTML и выполнять запросы XPath. Он основан на libxml.
XML Reader: XMLReader, как и DOM, основан на libxml. Расширение XMLReader - это синтаксический анализатор XML. Считыватель действует как курсор, движущийся вперед по потоку документа и останавливающийся на каждом узле по пути.
XML Parser: это расширение позволяет создавать анализаторы XML, а затем определять обработчики для различных событий XML. Каждый синтаксический анализатор XML также имеет несколько параметров, которые вы можете настроить. Он реализует push-синтаксический анализатор XML в стиле SAX.
Простой XML: расширение SimpleXML предоставляет очень простой и удобный в использовании набор инструментов для преобразования XML в объект, который можно обрабатывать с помощью обычных селекторов свойств и итераторов массивов.
Сторонние библиотеки [на основе libxml]:
FluentDom - Repo: FluentDOM предоставляет гибкий XML-интерфейс, похожий на jQuery, для DOMDocument в PHP. Он может загружать такие форматы, как JSON, CSV, JsonML, RabbitFish и другие. Может быть установлен через Composer.
HtmlPageDom: это PHP-библиотека для простого управления HTML-документами с помощью. Требуется DomCrawler из компонентов Symfony2 для обхода дерева DOM и расширяет его, добавляя методы для управления деревом DOM HTML-документов.
ZendDOM: Zend_Dom предоставляет инструменты для работы с документами и структурами DOM. В настоящее время они предлагают Zend_Dom_Query, который предоставляет унифицированный интерфейс для запросов к документам DOM с использованием селекторов XPath и CSS.
QueryPath: QueryPath - это библиотека PHP для управления XML и HTML. Он предназначен для работы не только с локальными файлами, но и с веб-службами и ресурсами баз данных. Он реализует большую часть интерфейса jQuery (включая селекторы в стиле CSS), но он сильно настроен для использования на стороне сервера. Может быть установлен через Composer.
Документ fDOM: fDOMDocument расширяет стандартную модель DOM для использования исключений во всех случаях ошибок вместо предупреждений или уведомлений PHP. Они также добавляют различные пользовательские методы и ярлыки для удобства и упрощения использования DOM.
Sabre / XML: saber / xml - это библиотека, которая обертывает и расширяет классы XMLReader и XMLWriter для создания простой системы отображения «xml в объект / массив» и шаблона проектирования. Запись и чтение XML являются однопроходными и поэтому могут быть быстрыми и требовать небольшого объема памяти для больших файлов xml.
FluidXML: FluidXML - это библиотека PHP для управления XML с помощью краткого и понятного API. Он использует XPath и шаблон свободного программирования, чтобы быть увлекательным и эффективным.
Сторонние библиотеки [не на основе libxml]:
PHP Simple HTML DOM Parser: синтаксический анализатор HTML DOM, написанный на PHP5+, позволяет очень легко манипулировать HTML, для этого требуется PHP 5+. Также поддерживает недопустимый HTML. Он извлекает содержимое из HTML в одну строку. Кодовая база ужасна и работает очень медленно.
PHP Html Parser: HPHtmlParser - это простой, гибкий анализатор HTML, который позволяет выбирать теги с помощью любого селектора CSS, например jQuery. Цель состоит в том, чтобы помочь в разработке инструментов, для которых требуется быстрый и простой способ очистки HTML независимо от того, действителен он или нет. Это медленно и требует слишком много мощности процессора.
Ganon (рекомендуется): универсальный токенизатор и парсер HTML / XML / RSS DOM. У него есть возможность манипулировать элементами и их атрибутами. Он поддерживает недопустимый HTML и UTF8. Он может выполнять расширенные CSS3-подобные запросы к элементам (например, jQuery - поддерживаются пространства имен). Украситель HTML (например, HTML Tidy). Минимизируйте CSS и Javascript. Это Сортировка атрибутов, изменение регистра символов, правильный отступ и т. Д. Расширяемость. Операции разделены на более мелкие функции для легкого переопределения, а также быстрого и легкого использования.
Веб-сервисы:
- Если вам не нравится программировать PHP, вы также можете использовать веб-службы. Внешний интерфейс ScraperWiki позволяет извлекать данные в желаемой форме для использования в сети или в собственных приложениях. Также вы можете извлечь информацию о состоянии любого скребка.
Я поделился всеми ресурсами, можете выбирать по своему вкусу, полезности и т. Д.