Jak parsować HTML / XML i wyciągać z niego informacje?
Jak parsować HTML / XML i wyciągać z niego informacje?
Odpowiedzi:
Wolę używać jednego z natywnych rozszerzeń XML, ponieważ są one dostarczane w pakiecie z PHP, są zwykle szybsze niż wszystkie biblioteki innych firm i dają mi pełną kontrolę nad znacznikami.
Rozszerzenie DOM pozwala na obsługę dokumentów XML za pomocą DOM API z PHP 5. Jest to implementacja dokumentu Object Model Model Core Level 3 W3C, niezależnego od platformy i języka interfejsu, który umożliwia programom i skryptom dynamiczny dostęp i aktualizację treść, struktura i styl dokumentów.
DOM jest w stanie analizować i modyfikować (zepsuty) HTML w świecie rzeczywistym i może wykonywać zapytania XPath . Opiera się na libxml .
Wydajność pracy z DOMem zajmuje trochę czasu, ale ten czas jest tego wart IMO. Ponieważ DOM jest interfejsem niezależnym od języka, znajdziesz implementacje w wielu językach, więc jeśli musisz zmienić język programowania, prawdopodobnie już wiesz, jak korzystać z interfejsu API DOM tego języka.
Podstawowy przykład użycia można znaleźć w Chwytanie atrybutu href elementu A, a ogólny przegląd pojęć można znaleźć w DOMDocument w php
Jak korzystać z rozszerzenia DOM zostało szczegółowo omówione w StackOverflow , więc jeśli zdecydujesz się go użyć, możesz być pewien, że większość problemów, na które natrafisz, można rozwiązać, wyszukując / przeglądając przepełnienie stosu.
Rozszerzenie XMLReader to analizator składni XML. Czytnik działa jak kursor poruszający się do przodu w strumieniu dokumentów i zatrzymujący się w każdym węźle po drodze.
XMLReader, podobnie jak DOM, oparty jest na libxml. Nie wiem, jak uruchomić moduł parsera HTML, więc szanse na użycie XMLReadera do analizowania uszkodzonego HTML mogą być mniej niezawodne niż użycie DOM, w którym możesz jawnie nakazać mu użycie modułu parsera HTML libxml.
Podstawowy przykład użycia można znaleźć przy pobieraniu wszystkich wartości ze znaczników h1 przy użyciu php
To rozszerzenie pozwala tworzyć parsery XML, a następnie definiować programy obsługi różnych zdarzeń XML. Każdy parser XML ma również kilka parametrów, które można dostosować.
Biblioteka parsera XML jest również oparta na libxml i implementuje parser wypychający XML w stylu SAX . Może być lepszym wyborem do zarządzania pamięcią niż DOM lub SimpleXML, ale będzie trudniejszy do pracy niż parser pull realizowany przez XMLReader.
Rozszerzenie SimpleXML zapewnia bardzo prosty i łatwy w użyciu zestaw narzędzi do konwersji XML do obiektu, który można przetwarzać za pomocą normalnych selektorów właściwości i iteratorów tablic.
SimpleXML jest opcją, gdy wiesz, że HTML jest prawidłowym XHTML. Jeśli musisz przeanalizować uszkodzony HTML, nie bierz nawet pod uwagę SimpleXml, ponieważ będzie się dusił.
Podstawowy przykład użycia można znaleźć w Prostym programie do CRUD wartości węzłów i węzłów pliku xml, i jest wiele dodatkowych przykładów w Podręczniku PHP .
Jeśli wolisz korzystać z biblioteki innej firmy, sugeruję użycie biblioteki lib, która faktycznie używa DOM / libxml pod spodem zamiast analizowania łańcucha.
FluentDOM zapewnia podobny do jQuery płynny interfejs XML dla DOMDocument w PHP. Selektory są zapisywane w XPath lub CSS (przy użyciu konwertera CSS na XPath). Obecne wersje rozszerzają DOM implementujący standardowe interfejsy i dodają funkcje z DOM Living Standard. FluentDOM może ładować formaty takie jak JSON, CSV, JsonML, RabbitFish i inne. Może być zainstalowany przez Composer.
Wa72 \ HtmlPageDom` to biblioteka PHP do łatwej manipulacji dokumentami HTML przy użyciu. Wymaga DomCrawler ze składników Symfony2 do przechodzenia przez drzewo DOM i rozszerza go poprzez dodanie metod manipulowania drzewem DOM dokumentów HTML.
phpQuery to oparty na serwerze, łańcuchowy interfejs API Document Object Model (DOM) oparty na selektorze CSS3 oparty na bibliotece JavaScript jQuery napisanej w PHP5 i zapewniający dodatkowy interfejs wiersza poleceń (CLI).
Zobacz także: https://github.com/electrolinux/phpquery
Zend_Dom zapewnia narzędzia do pracy z dokumentami i strukturami DOM. Obecnie oferujemy Zend_Dom_Query, który zapewnia zunifikowany interfejs do wysyłania zapytań do dokumentów DOM przy użyciu zarówno selektorów XPath, jak i CSS.
QueryPath to biblioteka PHP do manipulowania XML i HTML. Jest przeznaczony do pracy nie tylko z plikami lokalnymi, ale także z usługami internetowymi i zasobami bazy danych. Implementuje większość interfejsu jQuery (w tym selektory w stylu CSS), ale jest mocno dostosowany do użytku po stronie serwera. Może być zainstalowany przez Composer.
fDOMDocument rozszerza standardowy DOM o stosowanie wyjątków przy każdorazowych błędach zamiast ostrzeżeń i powiadomień PHP. Dodają także różne niestandardowe metody i skróty dla wygody i uproszczenia korzystania z DOM.
saber / xml to biblioteka, która otacza i rozszerza klasy XMLReader i XMLWriter, tworząc prosty system odwzorowywania „xml do obiektu / tablicy” i wzorzec projektowy. Pisanie i czytanie XML jest jednoprzebiegowe, dlatego może być szybkie i wymagać małej ilości pamięci w dużych plikach XML.
FluidXML to biblioteka PHP do manipulowania XML za pomocą zwięzłego i płynnego API. Wykorzystuje XPath i płynny schemat programowania, aby być zabawnym i skutecznym.
Zaletą budowania na DOM / libxml jest to, że otrzymujesz dobrą wydajność od razu po wyjęciu z pudełka, ponieważ bazujesz na natywnym rozszerzeniu. Jednak nie wszystkie biblioteki innych firm podążają tą drogą. Niektóre z nich wymienione poniżej
- Parser DOM HTML napisany w PHP5 + pozwala manipulować HTML w bardzo łatwy sposób!
- Wymagaj PHP 5+.
- Obsługuje nieprawidłowy HTML.
- Znajdź tagi na stronie HTML za pomocą selektorów takich jak jQuery.
- Wyodrębnij zawartość z HTML w jednym wierszu.
Generalnie nie polecam tego parsera. Baza kodów jest okropna, a sam parser jest raczej powolny i głodny pamięci. Nie wszystkie selektory jQuery (takie jak selektory potomne ) są możliwe. Każda biblioteka oparta na libxml powinna z łatwością osiągać lepsze wyniki.
PHPHtmlParser to prosty, elastyczny parser HTML, który pozwala wybierać tagi za pomocą dowolnego selektora css, takiego jak jQuery. Celem jest pomoc w opracowaniu narzędzi wymagających szybkiego i łatwego usuwania skrawków html, bez względu na to, czy są one ważne, czy nie! Ten projekt był pierwotnie wspierany przez sunra / php-simple-html-dom-parser, ale wydaje się, że wsparcie się zatrzymało, więc ten projekt jest moją adaptacją jego poprzedniej pracy.
Ponownie nie poleciłbym tego parsera. Jest raczej powolny przy dużym zużyciu procesora. Nie ma również funkcji czyszczenia pamięci utworzonych obiektów DOM. Problemy te skalują się szczególnie w przypadku zagnieżdżonych pętli. Sama dokumentacja jest niedokładna i błędna, bez odpowiedzi na poprawki od 14 kwietnia 16.
- Uniwersalny tokenizer i parser DOM HTML / XML / RSS
- Umiejętność manipulowania elementami i ich atrybutami
- Obsługuje nieprawidłowe HTML i UTF8
- Może wykonywać zaawansowane zapytania podobne do CSS3 na elementach (jak jQuery - obsługiwane przestrzenie nazw)
- Upiększacz HTML (jak HTML Tidy)
- Zminimalizuj CSS i JavaScript
- Sortuj atrybuty, zmieniaj wielkość znaków, poprawne wcięcia itp.
- Rozciągliwy
- Analizowanie dokumentów za pomocą wywołań zwrotnych opartych na bieżącym znaku / tokenie
- Operacje rozdzielone na mniejsze funkcje dla łatwego zastąpienia
- Szybko i łatwo
Nigdy go nie użyłem. Nie mogę powiedzieć, czy to coś dobrego.
Możesz użyć powyższego do analizowania HTML5, ale mogą pojawić się dziwactwa ze względu na znaczniki HTML5. W przypadku HTML5 należy rozważyć użycie dedykowanego analizatora składni, takiego jak
Implementacje parsera HTML opartego na specyfikacji WHATWG HTML5 w języku Python i PHP w celu zapewnienia maksymalnej kompatybilności z głównymi przeglądarkami na komputery stacjonarne.
Po sfinalizowaniu HTML5 możemy zobaczyć więcej dedykowanych analizatorów składni. Jest też post na blogu autorstwa W3 zatytułowany „ How to To for html 5 parsing”, który warto sprawdzić.
Jeśli nie masz ochoty programować PHP, możesz także korzystać z usług sieciowych. Ogólnie rzecz biorąc, znalazłem dla nich bardzo małą użyteczność, ale to tylko ja i moje przypadki użycia.
Zewnętrzny interfejs ScraperWiki pozwala wyodrębnić dane w formie, którą chcesz wykorzystać w Internecie lub we własnych aplikacjach. Możesz także wyodrębnić informacje o stanie dowolnego skrobaka.
Co najmniej zalecane , możesz wyodrębnić dane z HTML za pomocą wyrażeń regularnych . Ogólnie odradza się używanie wyrażeń regularnych w HTML.
Większość fragmentów, które można znaleźć w Internecie w celu dopasowania znaczników, jest krucha. W większości przypadków działają tylko dla bardzo konkretnego fragmentu HTML. Niewielkie zmiany znaczników, takie jak dodanie gdzieś białych znaków lub dodanie lub zmiana atrybutów w tagu, mogą spowodować, że regEx nie powiedzie się, jeśli nie zostanie poprawnie napisany. Przed użyciem RegEx na HTML powinieneś wiedzieć, co robisz.
Parsery HTML znają już składniowe reguły HTML. Wyrażeń regularnych należy uczyć dla każdego nowego RegEx, który napiszesz. RegEx są w niektórych przypadkach w porządku, ale tak naprawdę zależy to od twojego przypadku użycia.
Możesz pisać bardziej niezawodne analizatory składni , ale napisanie kompletnego i niezawodnego niestandardowego analizatora składni z wyrażeniami regularnymi to strata czasu, gdy wspomniane biblioteki już istnieją i wykonują znacznie lepszą robotę.
Zobacz także Parsing Html The Cthulhu Way
Jeśli chcesz wydać trochę pieniędzy, spójrz na
Nie jestem związany z PHP Architectem ani autorami.
Wypróbuj prosty parser DOM 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>';
// 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);
Wystarczy użyć DOMDocument-> loadHTML () i gotowe. Algorytm parsowania HTML libxml jest dość dobry i szybki, i wbrew powszechnemu przekonaniu, nie dusi się na źle sformułowanym HTML.
Dlaczego nie powinieneś i kiedy powinieneś używać wyrażeń regularnych?
Po pierwsze, często mylące: Regexps nie są przeznaczone do „ parsowania ” HTML. Regeksy mogą jednak „ wydobywać ” dane. Wydobywanie jest do czego są przeznaczone. Główną wadą ekstrakcji wyrażeń regularnych HTML w porównaniu z odpowiednimi zestawami narzędzi SGML lub bazowymi parserami XML jest ich składniowy wysiłek i różna niezawodność.
Weź pod uwagę, że wykonanie wyrażenia regularnego w pewnym stopniu zależnego od ekstrakcji HTML:
<a\s+class="?playbutton\d?[^>]+id="(\d+)".+? <a\s+class="[\w\s]*title
[\w\s]*"[^>]+href="(http://[^">]+)"[^>]*>([^<>]+)</a>.+?
jest znacznie mniej czytelny niż zwykły phpQuery lub odpowiednik QueryPath:
$div->find(".stationcool a")->attr("title");
Istnieją jednak konkretne przypadki użycia, w których mogą pomóc.
<!--
, które jednak są czasem bardziej przydatnymi kotwicami do ekstrakcji. W szczególności odmiany pseudo-HTML <$var>
lub reszty SGML są łatwe do oswojenia za pomocą wyrażeń regularnych.Czasami wskazane jest nawet wstępne wyodrębnienie fragmentu kodu HTML przy użyciu wyrażeń regularnych /<!--CONTENT-->(.+?)<!--END-->/
i przetworzenie pozostałej części za pomocą prostszych nakładek parsera HTML.
Uwaga: Mam tę aplikację , w której na przemian używam parsowania XML i wyrażeń regularnych. W zeszłym tygodniu parsowanie PyQuery zepsuło się, a regex nadal działał. Tak dziwne i sam nie potrafię tego wyjaśnić. Ale tak się stało.
Więc proszę, nie głosuj za odrzuceniem rzeczywistych względów, tylko dlatego, że nie pasują one do wyrażenia regularnego = zły mem. Ale nie głosujmy też za bardzo. To tylko sidenote dla tego tematu.
DOMComment
może czytać komentarze, więc nie ma powodu, aby używać do tego Regex.
DOM
używa libxml, a libxml ma osobny moduł analizatora HTML , który będzie używany podczas ładowania HTML, loadHTML()
dzięki czemu może bardzo ładować „rzeczywisty” (zepsuty) HTML.
phpQuery i QueryPath są bardzo podobne w replikacji płynnego API jQuery. Dlatego też są to dwa najprostsze podejścia do prawidłowej analizy HTML w PHP.
Przykłady dla QueryPath
Zasadniczo najpierw tworzysz drzewo DOM z zapytaniami na podstawie łańcucha HTML:
$qp = qp("<html><body><h1>title</h1>..."); // or give filename or URL
Powstały obiekt zawiera pełną reprezentację drzewa dokumentu HTML. Można go przechodzić przy użyciu metod DOM. Ale powszechnym podejściem jest używanie selektorów CSS jak w jQuery:
$qp->find("div.classname")->children()->...;
foreach ($qp->find("p img") as $img) {
print qp($img)->attr("src");
}
Najczęściej chcesz używać prostych #id
i / .class
lub DIV
znaczników do ->find()
. Ale możesz także użyć instrukcji XPath , które czasem są szybsze. Również typowe metody jQuery, takie jak ->children()
i, ->text()
szczególnie, ->attr()
upraszczają wyodrębnianie właściwych fragmentów HTML. (I już zdekodowały swoje encje SGML).
$qp->xpath("//div/p[1]"); // get first paragraph in a div
QueryPath pozwala również wstrzykiwać nowe tagi do stream ( ->append
), a następnie generować i aktualizować zaktualizowany dokument ( ->writeHTML
). Może nie tylko analizować zniekształcony HTML, ale także różne dialekty XML (z przestrzeniami nazw), a nawet wyodrębniać dane z mikroformatów HTML (XFN, vCard).
$qp->find("a[target=_blank]")->toggleClass("usability-blunder");
.
phpQuery lub QueryPath?
Ogólnie QueryPath lepiej nadaje się do manipulowania dokumentami. Podczas gdy phpQuery implementuje również niektóre pseudo metody AJAX (tylko żądania HTTP), aby bardziej przypominały jQuery. Mówi się, że phpQuery jest często szybszy niż QueryPath (z powodu mniejszej liczby ogólnych funkcji).
Aby uzyskać więcej informacji na temat różnic zobacz to porównanie na maszynie powrotnej z tagbyte.org . (Zaginęło oryginalne źródło, więc oto link do archiwum internetowego. Tak, nadal możesz znaleźć brakujące strony, ludzie).
A oto kompleksowe wprowadzenie do QueryPath .
Zalety
->find("a img, a object, div a")
Simple HTML DOM to świetny parser typu open source:
Traktuje elementy DOM w sposób zorientowany obiektowo, a nowa iteracja ma duży zasięg dla kodu niezgodnego. Istnieje również kilka świetnych funkcji, które można zobaczyć w JavaScript, takich jak funkcja „znajdź”, która zwróci wszystkie wystąpienia elementów tej nazwy znacznika.
Użyłem tego w wielu narzędziach, testując go na wielu różnych typach stron internetowych i myślę, że działa świetnie.
Jednym z ogólnych podejść, o których tu nie wspominałem, jest uruchamianie HTML-a przez Tidy , który można ustawić tak, aby wypluł gwarantowany XHTML. Następnie możesz użyć dowolnej starej biblioteki XML.
Ale na swój konkretny problem powinieneś rzucić okiem na ten projekt: http://fivefilters.org/content-only/ - to zmodyfikowana wersja algorytmu Readability , który został zaprojektowany w celu wyodrębnienia tylko treści tekstowej (nie nagłówków i stopki) ze strony.
Dla 1a i 2: Głosowałbym na nową klasę DOMCrawler Symfony Componet ( DomCrawler ). Ta klasa pozwala na zapytania podobne do Selektorów CSS. Spójrz na tę prezentację, aby zobaczyć przykłady z prawdziwego świata: news-of-the-symfony2-world .
Komponent jest przeznaczony do samodzielnego działania i może być używany bez Symfony.
Jedyną wadą jest to, że będzie działać tylko z PHP 5.3 lub nowszym.
Nawiasem mówiąc, jest to powszechnie określane jako zgarnianie ekranu . Biblioteka, której użyłem do tego, to Simple HTML Dom Parser .
Wcześniej stworzyliśmy całkiem sporo robotów dla naszych potrzeb. Na koniec dnia najlepiej sprawdzają się proste wyrażenia regularne. Chociaż biblioteki wymienione powyżej są dobre z tego powodu, że zostały utworzone, jeśli wiesz, czego szukasz, wyrażenia regularne są bezpieczniejszym sposobem, ponieważ możesz obsługiwać również niepoprawne struktury HTML / XHTML , które zawiodłyby, gdyby zostały załadowane przez większość parserów.
Polecam PHP Simple Parser DOM HTML .
Naprawdę ma fajne funkcje, takie jak:
foreach($html->find('img') as $element)
echo $element->src . '<br>';
To brzmi jak dobry opis zadania technologii XPath W3C . Łatwo jest wyrazić zapytania takie jak „zwróć wszystkie href
atrybuty w img
zagnieżdżonych znacznikach <foo><bar><baz> elements
”. Nie będąc maniakiem PHP, nie mogę powiedzieć, w jakiej formie XPath może być dostępny. Jeśli możesz wywołać program zewnętrzny w celu przetworzenia pliku HTML, powinieneś być w stanie użyć wersji XPath z wiersza poleceń. Aby uzyskać krótkie wprowadzenie, zobacz http://en.wikipedia.org/wiki/XPath .
Zewnętrzne alternatywy dla SimpleHtmlDom, które używają DOM zamiast parsowania ciągów: phpQuery , Zend_Dom , QueryPath i FluentDom .
Tak, w tym celu możesz użyć simple_html_dom. Jednak sporo pracowałem z simple_html_dom, szczególnie w przypadku złomowania stron internetowych i stwierdziłem, że jest zbyt podatny na ataki. Wykonuje podstawową pracę, ale i tak jej nie polecę.
Nigdy nie użyłem curl do tego celu, ale nauczyłem się, że curl może wykonać pracę znacznie wydajniej i jest o wiele bardziej solidny.
Uprzejmie sprawdź ten link: scraping-sites-with-curl
QueryPath jest dobry, ale należy uważać na „stan śledzenia”, ponieważ jeśli nie zdajesz sobie sprawy, co to znaczy, może to oznaczać, że tracisz dużo czasu na debugowanie, próbując dowiedzieć się, co się stało i dlaczego kod nie działa.
Oznacza to, że każde wywołanie zestawu wyników modyfikuje zestaw wyników w obiekcie, nie jest on łańcuchowy jak w jquery, gdzie każde łącze jest nowym zestawem, masz jeden zestaw, który jest wynikiem zapytania i każde wywołanie funkcji modyfikuje ten pojedynczy zestaw.
Aby uzyskać zachowanie podobne do jquery, musisz rozgałęzić się przed wykonaniem operacji typu filtruj / zmodyfikuj, co oznacza, że będzie znacznie dokładniej odzwierciedlać to, co dzieje się w jquery.
$results = qp("div p");
$forename = $results->find("input[name='forename']");
$results
teraz zawiera zestaw wyników input[name='forename']
NIE dla oryginalnego zapytania "div p"
, co mnie bardzo potknęło. Odkryłem, że QueryPath śledzi filtry i znaleziska oraz wszystko, co modyfikuje wyniki i przechowuje je w obiekcie. musisz to zrobić zamiast tego
$forename = $results->branch()->find("input[name='forname']")
wtedy $results
nie zostanie zmodyfikowany i będziesz mógł ponownie używać zestawu wyników, być może ktoś z dużo większą wiedzą może to trochę wyjaśnić, ale w zasadzie tak jest z tego, co znalazłem.
Advanced Html Dom jest prostym zamiennikiem DOM HTML HTML, który oferuje ten sam interfejs, ale jest oparty na DOM, co oznacza, że nie występują żadne powiązane problemy z pamięcią.
Posiada również pełną obsługę CSS, w tym rozszerzenia jQuery .
W przypadku HTML5 lib html5 jest porzucony od lat. Jedyną biblioteką HTML5, którą mogę znaleźć z ostatnimi rekordami aktualizacji i konserwacji, jest html5-php, który został właśnie wprowadzony do wersji beta nieco ponad tydzień temu.
Napisałem parser XML ogólnego przeznaczenia, który może z łatwością obsługiwać pliki GB. Jest oparty na XMLReaderze i jest bardzo łatwy w użyciu:
$source = new XmlExtractor("path/to/tag", "/path/to/file.xml");
foreach ($source as $tag) {
echo $tag->field1;
echo $tag->field2->subfield1;
}
Oto repozytorium github: XmlExtractor
Stworzyłem bibliotekę o nazwie PHPPowertools / DOM-Query , która pozwala na indeksowanie dokumentów HTML5 i XML tak samo jak w jQuery.
Pod maską wykorzystuje symfony / DomCrawler do konwersji selektorów CSS na selektory XPath . Zawsze używa tego samego DomDocument, nawet przy przekazywaniu jednego obiektu do drugiego, aby zapewnić przyzwoitą wydajność.
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>');
[...]
Biblioteka zawiera również własny autoloader o zerowej konfiguracji dla bibliotek kompatybilnych z PSR-0. Dołączony przykład powinien działać od razu bez dodatkowej konfiguracji. Alternatywnie możesz użyć go z kompozytorem.
Możesz spróbować użyć czegoś takiego jak HTML Tidy, aby wyczyścić dowolny „uszkodzony” HTML i przekonwertować HTML na XHTML, który możesz następnie przeanalizować za pomocą analizatora składni XML.
XML_HTMLSax
jest raczej stabilny - nawet jeśli nie jest już utrzymywany. Inną opcją może być przepuszczanie HTML przez HTML Tidy, a następnie parsowanie go za pomocą standardowych narzędzi XML.
Istnieje wiele sposobów przetwarzania DOM / HTML / XML, o których większość już wspomniano. Dlatego nie podejmę żadnej próby wymieniać je osobiście.
Chcę tylko dodać, że osobiście wolę używać rozszerzenia DOM i dlaczego:
I chociaż brakuje mi możliwości użycia selektorów CSS DOMDocument
, istnieje dość prosty i wygodny sposób na dodanie tej funkcji: podklasowanie DOMDocument
i dodawanie metod podobnych do JS querySelectorAll
i querySelector
metod do podklasy.
Do analizowania selektorów polecam użycie bardzo minimalistycznego komponentu CssSelector z frameworka Symfony . Ten składnik po prostu tłumaczy selektory CSS na selektory XPath, które można następnie wprowadzić do a, DOMXpath
aby pobrać odpowiednią listę Nodelist.
Następnie możesz użyć tej (wciąż bardzo niskiego poziomu) podklasy jako podstawy dla klas wyższych poziomów, przeznaczonych np. Do. analizuj bardzo specyficzne typy XML lub dodaj więcej zachowań podobnych do jQuery.
Poniższy kod pochodzi z mojej biblioteki DOM-Query i wykorzystuje opisaną przeze mnie technikę.
Do parsowania 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);
}
}
}
}
[...]
}
Zobacz także Analizowanie dokumentów XML za pomocą selektorów CSS przez twórcę Symfony, Fabiena Potenciera, na temat jego decyzji o utworzeniu komponentu CssSelector dla Symfony i sposobu jego użycia.
Dzięki FluidXML możesz wyszukiwać i iterować XML używając XPath i 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 i tablica z XML w trzech wierszach:
$xml = simplexml_load_string($xml_string);
$json = json_encode($xml);
$array = json_decode($json,TRUE);
Ta da!
Istnieje kilka powodów, aby nie analizować HTML za pomocą wyrażeń regularnych. Ale jeśli masz całkowitą kontrolę nad tym, jaki kod HTML zostanie wygenerowany, możesz to zrobić za pomocą prostego wyrażenia regularnego.
Powyżej jest to funkcja, która analizuje HTML przez wyrażenie regularne. Zauważ, że ta funkcja jest bardzo czuła i wymaga, aby HTML przestrzegał pewnych reguł, ale działa bardzo dobrze w wielu scenariuszach. Jeśli potrzebujesz prostego parsera i nie chcesz instalować bibliotek, spróbuj:
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/")));
Utworzyłem bibliotekę o nazwie HTML5DOMDocument, która jest bezpłatnie dostępna na stronie https://github.com/ivopetkov/html5-dom-document-php
Obsługuje również selektory zapytań, które moim zdaniem będą niezwykle pomocne w twoim przypadku. Oto przykładowy kod:
$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;
Jeśli znasz selektor jQuery, możesz użyć ScarletsQuery dla 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);
Ta biblioteka zazwyczaj zajmuje mniej niż 1 sekundę na przetwarzanie HTML offline.
Akceptuje również nieprawidłowy kod HTML lub brakujący cytat na atrybutach tagu.
Najlepsza metoda parsowania 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;
}