Як можна проаналізувати HTML / XML і витягти з нього інформацію?
Як можна проаналізувати HTML / XML і витягти з нього інформацію?
Відповіді:
Я вважаю за краще використовувати одне з власних розширень XML, оскільки вони поставляються в комплекті з PHP, як правило, швидше, ніж усі сторонні розширення та надають мені весь контроль, який мені потрібен над розміткою.
Розширення DOM дозволяє працювати з документами XML за допомогою API DOM з PHP 5. Це реалізація документа W3C Document Object Model Core Level 3, нейтральний для платформи та мови інтерфейс, що дозволяє програмам та сценаріям динамічно отримувати доступ та оновлювати зміст, структура та стиль документів.
DOM здатний аналізувати та змінювати HTML-код реального світу (зламаного), і він може робити XPath-запити . Він заснований на libxml .
Для отримання продуктивності з DOM потрібен певний час, але цей час вартий того, щоб це IMO. Оскільки DOM - це мовно-агностичний інтерфейс, ви знайдете реалізацію на багатьох мовах, тому якщо вам потрібно змінити мову програмування, швидше за все, ви вже будете знати, як використовувати API DOM цієї мови тоді.
Основний приклад використання можна знайти в захопленні атрибута href елемента A, а загальний концептуальний огляд можна знайти на DOMDocument в php
Як використовувати розширення DOM широко висвітлено в StackOverflow , тож якщо ви вирішите його використовувати, ви можете бути впевнені, що більшість проблем, які ви стикаєтеся , можна вирішити шляхом пошуку / перегляду переповнення стека.
Розширення XMLReader - це синтаксичний аналізатор XML. Зчитувач виступає як курсор, який рухається вперед по потоку документів і зупиняється на кожному вузлі на шляху.
XMLReader, як і DOM, заснований на libxml. Я не знаю, як запустити модуль HTML-парсера, тому шанси використання XMLReader для розбору зламаного HTML можуть бути менш надійними, ніж використання DOM, де ви можете чітко сказати йому використовувати модуль HTML-парсера libxml.
Основний приклад використання можна знайти при отриманні всіх значень з h1 тегів за допомогою php
Це розширення дозволяє створювати XML-аналізатори та потім визначати обробники для різних подій XML. Кожен аналізатор XML також має кілька параметрів, які ви можете налаштувати.
Бібліотека XML Parser також базується на libxml та реалізує XML- розбірник стилів XML у стилі SAX . Це може бути кращим вибором для управління пам'яттю, ніж DOM або SimpleXML, але працювати буде складніше, ніж аналізатор тяжіння, реалізований XMLReader.
Розширення SimpleXML забезпечує дуже простий і легко зручний набір інструментів для перетворення XML в об'єкт, який можна обробити звичайними селекторами властивостей та ітераторами масиву.
SimpleXML - це варіант, коли ви знаєте, що HTML є дійсним XHTML. Якщо вам потрібно розібрати зламаний HTML, навіть не розглядайте SimpleXml, оскільки він задихнеться.
Основний приклад використання можна знайти в Простій програмі для значень вузла та вузла CRUD у файлі xml, і в Посібнику з PHP є багато додаткових прикладів .
Якщо ви віддаєте перевагу використовувати сторонній lib, я б запропонував використовувати lib, який фактично використовує 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, використовуючи для цього потрібний DomCrawler з компонентів Symfony2 для переходу до дерева DOM та розширення, додаючи методи маніпулювання деревом DOM з HTML-документів.
phpQuery - це серверний, керований селектором CSS3, API, орієнтований на модель об'єкта документа (DOM), заснований на бібліотеці jQuery JavaScript, написаній на 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.
saber / xml - це бібліотека, яка обгортає та розширює класи XMLReader та XMLWriter, щоб створити просту систему картографування "xml для об'єкта / масиву" та шаблон дизайну. Написання та читання 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-красуня (наприклад, 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 The Cthulhu Way
Якщо ви хочете витратити трохи грошей, погляньте
Я не пов'язаний з архітектором PHP або авторами.
Спробуйте простий парсер 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.
Чому не слід і коли слід використовувати регулярні вирази?
По-перше, поширена помилка: Regexps не для " розбору " 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 зламався, і регулярний вираз продовжував працювати. Так дивно, і я не можу сам це пояснити. Але так сталося.
Тож, будь ласка, не голосуйте з реальних міркувань лише тому, що це не відповідає регексу = злому мему. Але давайте також не будемо занадто голосувати за це. Це просто сторонне позначення цієї теми.
DOMComment
може читати коментарі, тому немає причин використовувати Regex для цього.
DOM
використовує libxml, а libxml має окремий модуль HTML-аналізатора, який буде використовуватися при завантаженні HTML, loadHTML()
щоб він міг значно завантажувати "реальний світ" (читати ламаний) HTML.
phpQuery і QueryPath дуже схожі на тиражування вільно JQuery API. Ось чому це два найпростіші підходи до правильного розбору 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")
Простий HTML DOM - це чудовий аналізатор з відкритим кодом:
Він обробляє елементи DOM об'єктно-орієнтованим способом, і нова ітерація має багато покриття для невідповідного коду. Існує також кілька чудових функцій, як ви бачите в JavaScript, наприклад, функція "знайти", яка повертає всі екземпляри елементів цього імені тегу.
Я використовував це в ряді інструментів, тестуючи його на багатьох різних веб-сторінках, і я думаю, що це чудово працює.
Один загальний підхід, якого я не бачив тут, - це запускати HTML через Tidy , який можна встановити, щоб виплюнути гарантовано дійсний XHTML. Тоді ви можете використовувати будь-яку стару бібліотеку XML на ній.
Але до вашої конкретної проблеми слід поглянути на цей проект: http://fivefilters.org/content-only/ - це модифікована версія алгоритму читабельності , яка призначена для вилучення лише текстового вмісту (а не заголовків) і колонтитули) зі сторінки.
За 1а та 2: Я би проголосував за новий клас Symboly Componet DOMCrawler ( DomCrawler ). Цей клас дозволяє запити, подібні до CSS Selectors. Погляньте на цю презентацію на приклади реального світу: новини-про-символу2-світу .
Компонент розроблений для самостійної роботи і може використовуватися без Symfony.
Єдиний недолік - це те, що він буде працювати лише з PHP 5.3 або новішою версією.
Це , до речі, називають екрануванням екрана . Бібліотека, яку я використав для цього, - простий 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
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
не буде змінено, і ви можете повторно використовувати набір результатів знову і знову, можливо, хтось, хто має набагато більше знань, може це трохи очистити, але це в основному так, як це я знайшов.
Розширений 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;
}
Ось github repo: XmlExtractor
Я створив бібліотеку під назвою 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. Приклад, що входить, повинен працювати з вікна без додаткової конфігурації. Як варіант, ви можете використовувати його з композитором.
Ви можете спробувати використати щось на кшталт HTML Tidy, щоб очистити будь-який "зламаний" HTML і перетворити HTML в XHTML, який ви зможете потім проаналізувати за допомогою аналізатора XML.
XML_HTMLSax
досить стабільний - навіть якщо він більше не підтримується. Іншим варіантом може бути передавання HTML через Html Tidy, а потім його розбір зі стандартними інструментами XML.
Існує багато способів обробки HTML / XML DOM, про які більшість вже згадувалося. Отже, я не буду робити жодних спроб перерахувати їх самі.
Я просто хочу додати, що я особисто вважаю за краще використовувати розширення DOM і чому:
І хоча мені не вистачає можливості використовувати селектори CSS для DOMDocument
, є досить простий і зручний спосіб додати цю функцію: підкласифікація DOMDocument
та додавання JS-подібних querySelectorAll
таquerySelector
методи підкласу.
Для розбору селекторів я рекомендую використовувати дуже мінімалістичний компонент CssSelector з рамки Symfony . Цей компонент просто переводить селектори CSS у селектори XPath, які потім можуть бути передані уDOMXpath
передані для отримання відповідного Nodelist.
Потім ви можете використовувати цей (ще дуже низький рівень) підклас як основу для класів більш високого рівня, призначених наприклад. проаналізуйте дуже специфічні типи XML або додайте більше поведінки, подібної jQuery.
Код нижче виходить з моєї бібліотеки запитів DOM і використовує описану нами техніку.
Для розбору 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 Фабієна Потенцьє про його рішення створити компонент CssSelector для Symfony та способи його використання.
За допомогою 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');
});
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;
}