Jak parsować i przetwarzać HTML / XML w PHP?

Jak można parsować HTML / XML i wyodrębniać z niego informacje?

Author: RobertPitt, 2010-08-26

29 answers

Natywne rozszerzenia XML

Wolę używać jednego z natywnych rozszerzeń XML , ponieważ są one dołączone do PHP, są zwykle szybsze niż wszystkie biblioteki stron trzecich i dają mi całą kontrolę nad znacznikami.

DOM

Rozszerzenie DOM pozwala na operowanie na dokumentach XML poprzez DOM API z PHP 5. Jest to implementacja W3C ' s Document Object Model Core Level 3, neutralnego dla platformy i języka interfejsu, który pozwala programy i skrypty do dynamicznego dostępu i aktualizacji zawartości, struktury i stylu dokumentów.

DOM jest w stanie parsować i modyfikować rzeczywisty (uszkodzony) HTML i może wykonywać zapytania XPath. Jest oparty na libxml .

Potrzeba trochę czasu, aby uzyskać produktywność z DOM, 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 chcesz zmienić swój język programowania, są szanse, że będziesz już wiedział, jak używać tego języka Dom API.

Podstawowy przykład użycia można znaleźć w pobierając atrybut href elementu A , a ogólny przegląd pojęciowy można znaleźć w DOMDocument w php

Sposób korzystania z rozszerzenia DOM został szeroko omówiony w StackOverflow, więc jeśli zdecydujesz się go użyć, możesz być pewien, że większość problemów, które napotkasz, może zostać rozwiązana przez wyszukiwanie / przeglądanie stosu Przepełnienie.

XMLReader

Rozszerzenie XmlReader jest parserem XML pull. Czytnik działa jak kursor poruszający się do przodu po strumieniu dokumentu i zatrzymujący się na każdym węźle po drodze.

XMLReader, podobnie jak DOM, bazuje na libxml. Nie wiem, jak uruchomić moduł parsera HTML, więc możliwe, że użycie XMLReader do parsowania zepsutego HTML może być mniej wytrzymałe niż użycie DOM, gdzie można wyraźnie powiedzieć mu, aby używał parsera HTML libxml Moduł.

Podstawowy przykład użycia można znaleźć w pobierając wszystkie wartości ze znaczników h1 za pomocą php

Parser XML

To rozszerzenie pozwala tworzyć parsery XML, a następnie definiować programy obsługi dla różnych zdarzeń XML. Każdy parser XML ma również kilka parametrów, które można dostosować.

Biblioteka parserów XML jest również oparta na libxml i implementuje parser XML push 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 zaimplementowany przez XMLReader.

SimpleXml

Rozszerzenie SimpleXML zapewnia bardzo prosty i łatwy w użyciu zestaw narzędzi do konwersji XML do obiektu, który może być przetwarzany za pomocą zwykłych selektorów właściwości i iteratorów tablicy.

SimpleXML jest opcją, gdy wiesz, że HTML jest prawidłowy XHTML. Jeśli chcesz przeanalizować zepsuty HTML, nawet nie bierz pod uwagę SimpleXml, ponieważ będzie duszenie.

Podstawowy przykład użycia można znaleźć w prosty program do CRUD node i node wartości pliku xml i istnieje wiele dodatkowych przykładów w instrukcji PHP .


Biblioteki stron trzecich (oparte na libxml)

Jeśli wolisz korzystać z lib stron trzecich, sugerowałbym użycie lib, które faktycznie używa DOM/libxml pod spodem zamiast parsowania łańcuchów.

FluentDom

FluentDOM zapewnia jQuery-jak 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ą standardowe interfejsy implementujące DOM i dodają funkcje ze standardu Dom Living. FluentDOM może ładować formaty takie jak JSON, CSV, JsonML, RabbitFish i inne. Może być zainstalowany przez Composer.

HtmlPageDom

Wa72 \ HtmlPageDom ' jest biblioteką PHP do łatwej manipulacji HTML dokumenty z niego korzystające wymagają DomCrawler z Symfony2 komponenty do trawersowania Drzewo DOM i rozszerza je dodając metody manipulowania DOM drzewo dokumentów HTML.

PhpQuery (nie aktualizowane od lat)

PhpQuery jest serwerowym, łańcuchowym API CSS3 selector driven Document Object Model (DOM) opartym na bibliotece JavaScript Jquery napisanej w PHP5 i zapewnia dodatkowy interfejs wiersza poleceń (CLI).

Zobacz też: https://github.com/electrolinux/phpquery

Zend_Dom

Zend_Dom dostarcza narzędzia do pracy z dokumentami i strukturami DOM. Obecnie oferujemy klasę Zend_Dom_Query, która zapewnia zunifikowany interfejs do odpytywania dokumentów DOM przy użyciu selektorów XPath i CSS.

QueryPath

QueryPath jest biblioteką PHP do manipulacji XML i HTML. Przeznaczony jest do pracy nie tylko z plikami lokalnymi, ale także z Usługi internetowe i zasoby baz danych. Implementuje wiele interfejsu jQuery (w tym selektory stylu CSS), ale jest mocno dostrojony do użytku po stronie serwera. Może być zainstalowany przez Composer.

FDOMDocument

Fdomdocument rozszerza standard DOM, aby używać WYJĄTKÓW przy każdej okazji błędów zamiast ostrzeżeń lub powiadomień PHP. Dodają również różne niestandardowe metody i skróty dla wygody i uproszczenia użytkowania DOM.

Sabre / xml

Sabre / xml jest biblioteką, która owija i rozszerza klasy XMLReader i XmlWriter w celu utworzenia prostego systemu mapowania "xml to object / array" i wzorca projektowego. Zapis i odczyt XML jest jednoprzebiegowy i dlatego może być szybki i wymaga małej pamięci na dużych plikach xml.

FluidXML

FluidXML jest biblioteką PHP do manipulowania XML z zwięzłym i płynnym API. Wykorzystuje XPath i płynny wzór programowania, aby był zabawny i skuteczny.


3rd-Party (nie oparte na libxml)

Zaletą budowania w oparciu o DOM / libxml jest to, że uzyskujesz dobrą wydajność po wyjęciu z pudełka, ponieważ bazujesz na natywnym rozszerzeniu. Jednak nie wszystkie 3rd-party libs iść tą drogą. Niektóre z nich wymienione poniżej

PHP Simple HTML DOM Parser

  • HTML Parser DOM napisany w PHP5 + pozwala manipulować HTML w bardzo łatwy sposób!
  • Wymagaj PHP 5+.
  • obsługuje nieprawidłowy HTML.
  • Znajdź tagi na stronie HTML z selektorami, tak jak jQuery.
  • wyodrębnij zawartość z HTML w jednej linii.

Generalnie nie polecam tego parsera. Baza kodowa 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 z bibliotek opartych na libxml powinna przewyższać to łatwo.

PHP Html Parser

PHPHtmlParser jest prostym, elastycznym parserem html, który pozwala wybrać tagi za pomocą dowolnego selektora css, takiego jak jQuery. Celem jest pomoc w rozwoju narzędzi, które wymagają szybkiego, łatwego sposobu na pozbycie się kodu html, niezależnie od tego, czy jest on poprawny, czy nie! Ten projekt był oryginalny wspierany przez sunra / PHP-simple-html-dom-parser ale wsparcie wydaje się przestać więc ten projekt jest moją adaptacją jego poprzedniego praca.

Ponownie, nie polecam tego parsera. Jest raczej powolny przy wysokim zużyciu procesora. Nie ma również funkcji do czyszczenia pamięci wytworzonych obiektów DOM. Problemy te skalują się szczególnie w przypadku zagnieżdżonych pętli. Sama dokumentacja jest niedokładna i źle napisana, bez odpowiedzi na poprawki od 14 Apr 16.

Ganon

  • uniwersalny tokenizer i HTML / XML/RSS DOM Parser
    • umiejętność manipulowania elementami i ich atrybuty
    • obsługuje nieprawidłowy HTML i UTF8
  • Może wykonywać zaawansowane zapytania podobne do CSS3 na elementach (takie jak jQuery -- obsługiwane przestrzenie nazw)
  • a HTML beautifier (like HTML Tidy)
    • Minify CSS i Javascript
    • sortowanie atrybutów, zmiana wielkości liter, poprawne wcięcia itp.
  • Extensible
    • parsowanie dokumentów za pomocą wywołań zwrotnych na podstawie bieżącego znak / token
    • operacje rozdzielone na mniejsze funkcje dla łatwego nadpisywania
  • szybko i łatwo
Nigdy go nie używałem. Nie wiem, czy jest dobry.

HTML 5

Możesz użyć powyższego do parsowania HTML5, ale mogą być dziwactwa ze względu na znaczniki, na które pozwala HTML5. Więc dla HTML5 warto rozważyć użycie dedykowanego parsera, takiego jak

Html5lib

A Python and PHP implementacja parsera HTML opartego na specyfikacji WHATWG HTML5 dla maksymalnej kompatybilności z głównymi przeglądarkami internetowymi.

Możemy zobaczyć więcej dedykowanych parserów po sfinalizowaniu HTML5. Jest też blog autorstwa W3 ' s zatytułowany How-To for html 5 parsing, który warto sprawdzić.


WebServices

Jeśli nie masz ochoty na programowanie PHP, możesz również skorzystać z usług internetowych. Ogólnie rzecz biorąc, znalazłem bardzo mało użyteczności dla nich, ale to tylko ja i moje przypadki użycia.

YQL

Usługa internetowa YQL umożliwia aplikacjom odpytywanie, filtrowanie i łączenie danych z różnych źródeł w Internecie. Instrukcje YQL mają składnię podobną do SQL, znaną każdemu programiście z doświadczeniem w bazach danych.

ScraperWiki .

Zewnętrzny interfejs ScraperWiki pozwala na wyodrębnienie danych w formie, którą chcesz użyć w Internecie lub we własnych aplikacjach. Można również wyodrębnić informacje o stanie każdego skrobaka.


Wyrażenia Regularne

Last I least recommended , możesz wyodrębnić dane z HTML za pomocą wyrażeń regularnych . Generalnie odradzane jest używanie wyrażeń regularnych w HTML.

Większość fragmentów, które znajdziesz w sieci, aby dopasować znaczniki, jest krucha. W większości przypadków działają tylko dla bardzo konkretnego fragmentu HTML. Drobne zmiany znaczników, np. dodanie spacji lub dodanie, lub zmiana atrybutów w znaczniku, może sprawić, że wyrażenie regularne zawiedzie, gdy nie jest poprawnie napisane. Powinieneś wiedzieć, co robisz przed użyciem RegEx w HTML.

Parsery HTML znają już reguły składniowe HTML. Dla każdego nowego wyrażenia regularnego należy uczyć się wyrażeń regularnych. RegEx są w porządku w niektórych przypadkach, ale to naprawdę zależy od przypadku użycia.

TY możesz pisać bardziej niezawodne parsery , ale pisząc kompletny i niezawodny Niestandardowy parser z regularnym wyrażenia to strata czasu, gdy wspomniane biblioteki już istnieją i wykonują znacznie lepszą pracę w tym zakresie.

Zobacz też Parsing Html The Cthulhu Way


Książki

Jeśli chcesz wydać trochę pieniędzy, spójrz na

Nie jestem związany z architektem PHP ani jego autorami.

 1749
Author: Gordon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-03 18:57:44

Spróbuj prosty HTML Parser DOM

  • Parser DOM HTML napisany w PHP 5+, który pozwala manipulować HTML w bardzo łatwy sposób!
  • Wymagaj PHP 5+.
  • obsługuje nieprawidłowy HTML.
  • Znajdź tagi na stronie HTML z selektorami, tak jak jQuery.
  • wyodrębnij zawartość z HTML w jednej linii.
  • Pobierz


Przykłady:

Jak uzyskać HTML elementy:

// 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>';


Jak modyfikować elementy 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;


Wyodrębnij zawartość z HTML:

// Dump contents (without tags) from HTML
echo file_get_html('http://www.google.com/')->plaintext;


Scraping 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);
 310
Author: Naveed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-28 17:41:16

Wystarczy użyć DOMDocument - >loadHTML() i gotowe. algorytm parsowania HTML libxml jest dość dobry i szybki i wbrew powszechnemu przekonaniu nie dławi się wadliwym HTML.

 224
Author: Edward Z. Yang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-26 20:02:44

Dlaczego nie powinieneś i Kiedy powinieneś używać wyrażeń regularnych?

Po pierwsze, powszechny błąd: wyrażenia regularne nie są dla "parsowanie" HTML. Wyrażenia regularne mogą jednak "ekstrakt" data. Do tego są stworzeni. Główną wadą ekstrakcji HTML regex nad odpowiednimi zestawami narzędzi SGML lub bazowymi parserami XML są ich wysiłek składniowy i zmienna niezawodność.

Weź pod uwagę, że wykonanie pewnego, niezawodnego ekstrakcji HTML regex:

<a\s+class="?playbutton\d?[^>]+id="(\d+)".+?    <a\s+class="[\w\s]*title
[\w\s]*"[^>]+href="(http://[^">]+)"[^>]*>([^<>]+)</a>.+?

Jest o wiele mniej czytelny niż zwykły odpowiednik phpquery lub querypath:

$div->find(".stationcool a")->attr("title");

Istnieją jednak szczególne przypadki użycia, w których mogą pomóc.

  • wiele frontendów przejazdu DOM nie ujawnia komentarzy HTML <!--, które jednak czasami są bardziej użytecznymi anchorami do ekstrakcji. W szczególności pseudo-HTML odmiany <$var> lub pozostałości SGML są łatwe do oswojenia za pomocą wyrażeń regularnych.
  • często wyrażenia regularne mogą zapisywać post-processing. Jednak HTML byty często wymagają ręcznej opieki.
  • i wreszcie, dla e xtremely prostych zadań Jak wyodrębnianie

Czasami zaleca się nawet wstępne wyodrębnienie fragmentu HTML za pomocą wyrażeń regularnych /<!--CONTENT-->(.+?)<!--END-->/, a resztę przetworzyć przy użyciu prostszych interfejsów parsera HTML.

Uwaga: I właściwie mam aplikację , w której używam XML parsingu i wyrażeń regularnych alternatywnie. W zeszłym tygodniu parsowanie PyQuery pękło, a regex nadal działał. Tak dziwne i nie potrafię tego wyjaśnić. Ale tak się stało.
Więc proszę, nie głosuj na prawdziwe rozważania, tylko dlatego, że nie pasuje do regex=evil meme. Ale nie głosujmy za bardzo. To tylko wskazówka na ten temat.

 139
Author: mario,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-07 10:43:47

PhpQuery i QueryPath są bardzo podobne w replikacji płynnego API jQuery. Dlatego też są to dwa najprostsze podejścia do poprawnie parsowania HTML w PHP.

Przykłady dla QueryPath

Zasadniczo najpierw tworzysz drzewo DOM z zapytaniem z ciągu HTML:

 $qp = qp("<html><body><h1>title</h1>..."); // or give filename or URL

Wynikowy obiekt zawiera pełną reprezentację drzewa dokumentu HTML. Można go przemierzać za pomocą metod DOM. Ale wspólne podejście polega na używaniu selektorów CSS jak w jQuery:

 $qp->find("div.classname")->children()->...;

 foreach ($qp->find("p img") as $img) {
     print qp($img)->attr("src");
 }

Głównie chcesz używać prostych selektorów znaczników #id i .class lub DIV dla ->find(). Ale można również użyć XPath , które czasami są szybsze. Również typowe metody jQuery, takie jak ->children() i ->text(), a szczególnie ->attr(), upraszczają wyodrębnianie odpowiednich fragmentów HTML. (I mają już dekodowane encje SGML.)

 $qp->xpath("//div/p[1]");  // get first paragraph in a div

QueryPath umożliwia również wstrzykiwanie nowych tagów do strumienia (->append), a później wyjście i poprawienia zaktualizowanego dokumentu (->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 czy QueryPath?

Ogólnie QueryPath lepiej nadaje się do manipulacji dokumentami. Podczas gdy phpQuery implementuje również niektóre metody pseudo AJAX (tylko żądania HTTP), aby bardziej przypominać jQuery. Mówi się, że phpQuery jest często szybsze niż QueryPath (z powodu mniejszej liczby ogólnych funkcji).

Aby uzyskać więcej informacji na temat różnic patrz to porównanie na wayback machine z tagbyte.org . (oryginalne źródło zaginęło, więc tutaj jest link do archiwum internetowego. Tak, nadal możesz zlokalizować brakujące strony, ludzie.)

A oto obszerne wprowadzenie do QueryPath.

Zalety

  • prostota i niezawodność
  • proste w użyciu alternatywy ->find("a img, a object, div a")
  • poprawne dane unescaping (w porównaniu z greppingiem wyrażeń regularnych)
 127
Author: mario,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-23 04:57:04

Prosty HTML DOM jest świetnym parserem open-source:

Simplehtmldom.sourceforge

Traktuje elementy DOM w sposób obiektowy, a nowa iteracja ma wiele zalet dla kodu niezgodnego. Istnieją również wspaniałe funkcje, takie jak w JavaScript, takie 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 to działa świetnie.

 85
Author: Robert Elwell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-28 17:39:31

Jedno ogólne podejście, o którym tu nie wspomniałem, to uruchamianie HTML przez Tidy , które można ustawić tak, aby wypluć gwarantowany poprawny XHTML. Następnie możesz użyć dowolnej starej biblioteki XML.

Ale do twojego konkretnego problemu, powinieneś rzucić okiem na ten projekt: http://fivefilters.org/content-only/ -- jest to zmodyfikowana wersja algorytmuReadability , który został zaprojektowany do wyodrębniania tylko treści tekstowych (nie nagłówków i stopek) ze strony.

 58
Author: Eli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-01 02:04:38

Dla 1a i 2: zagłosowałbym na nową klasę Symfony Componet DOMCrawler (DomCrawler ). Ta klasa pozwala na zapytania podobne do selektorów CSS. Spójrz na tę prezentację dla rzeczywistych przykładów: news-of-the-symfony2-world .

Komponent jest przeznaczony do pracy samodzielnej i może być używany bez Symfony.

Jedyną wadą jest to, że będzie działać tylko z PHP 5.3 lub nowszym.

 54
Author: Timo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-14 10:33:52

Jest to powszechnie określane jako screen scraping , nawiasem mówiąc. Biblioteka, której użyłem to prosty HTML Parser Dom.

 51
Author: Joel Verhagen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-26 17:20:17

Stworzyliśmy już sporo crawlerów na nasze potrzeby. Na koniec dnia, to zwykle proste wyrażenia regularne, które robią to najlepiej. Chociaż biblioteki wymienione powyżej są dobre ze względu na powód, dla którego zostały utworzone, jeśli wiesz, czego szukasz, wyrażenia regularne są bezpieczniejszym sposobem, ponieważ możesz obsługiwać również nieprawidłowy HTML/struktury XHTML , które nie powiodłyby się, gdyby zostały załadowane przez większość parserów.

 40
Author: jancha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-31 22:48:43

Polecam PHP prosty HTML Parser DOM .

Ma naprawdę fajne funkcje, takie jak:

foreach($html->find('img') as $element)
       echo $element->src . '<br>';
 37
Author: Greg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-28 17:42:57

To brzmi jak dobry opis zadania technologii W3C XPath. Łatwo jest wyrażać zapytania, takie jak " return all href atrybuty w img znacznikach zagnieżdżonych w <foo><bar><baz> elements."Nie będąc buforem PHP, nie mogę ci powiedzieć, w jakiej formie XPath może być dostępny. Jeśli możesz wywołać zewnętrzny program do przetwarzania pliku HTML, powinieneś być w stanie użyć wersji XPath z linii poleceń. Aby uzyskać szybkie wprowadzenie, zobacz http://en.wikipedia.org/wiki/XPath .

 35
Author: Jens,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-14 19:08:11

Alternatywy innych firm dla SimpleHtmlDom, które używają DOM zamiast parsowania łańcuchów: phpQuery, Zend_Dom, QueryPath i FluentDom .

 28
Author: Amal Murali,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-26 18:31:35

Tak możesz użyć simple_html_dom do tego celu. Jednak pracowałem dość dużo z simple_html_dom, szczególnie w przypadku złomowania stron internetowych i stwierdziłem, że jest zbyt podatny. Wykonuje podstawową pracę, ale i tak nie polecam.

Nigdy nie używałem curl do tego celu, ale nauczyłem się, że curl może wykonywać pracę znacznie wydajniej i jest o wiele bardziej solidny.

Uprzejmie sprawdź ten link: scraping-websites-with-curl

 22
Author: Rafay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-14 10:40:04

QueryPath jest dobry, ale uważaj 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 to łańcuchowalne jak w jquery, gdzie każde połączenie jest nowym zestawem, masz pojedynczy zestaw, który jest wynikiem twojego zapytania i każde wywołanie funkcji modyfikuje ten pojedynczy zestaw. gotowi.

Aby uzyskać zachowanie podobne do jquery, musisz rozgałęziać się przed wykonaniem operacji filter/modify like, co oznacza, że będzie bardziej odzwierciedlać to, co dzieje się w jquery.

$results = qp("div p");
$forename = $results->find("input[name='forename']");

$results Teraz zawiera zestaw wyników dla input[name='forename'], a nie oryginalne zapytanie "div p" to mnie potknęło, co znalazłem to QueryPath śledzi filtry i znaleziska oraz wszystko, co modyfikuje Twoje wyniki i przechowuje je w obiekcie. musisz to zrobić. zamiast

$forename = $results->branch()->find("input[name='forname']")

Wtedy $results nie zostanie zmodyfikowany i możesz ponownie użyć zestawu wyników raz po raz, być może ktoś z większą wiedzą może to trochę wyjaśnić, ale to w zasadzie tak z tego, co znalazłem.

 22
Author: Christopher Thomas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-31 10:14:42

Advanced Html Dom jest prostym zamiennikiem HTML DOM , który oferuje ten sam interfejs, ale jest oparty na DOM, co oznacza, że żaden z powiązanych problemów z pamięcią nie występuje.

Posiada również pełną obsługę CSS, w tym rozszerzenia jQuery .

 18
Author: pguardiario,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-28 16:48:57

Stworzyłem bibliotekę o nazwie PHPPowertools / Dom-zapytanie, który pozwala na indeksowanie dokumentów HTML5 i XML, tak jak to robisz z jQuery.

Pod maską, używa symfony / DomCrawler do konwersji selektorów CSS na selektory XPath. Zawsze używa tego samego dokumentu Domd, nawet podczas przekazywania jednego obiektu do drugiego, aby zapewnić przyzwoitą wydajność.


Przykładowe użycie:

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>');

[...]

Obsługiwane metody :


  1. zmiana nazwy na "Wybierz", z oczywistych powodów
  2. zmiana nazwy na 'void', ponieważ 'empty' jest słowem zastrzeżonym w PHP

Uwaga:

biblioteka zawiera również własny autoloader z zerową konfiguracją dla bibliotek kompatybilnych z PSR - 0. Dołączony przykład powinien działać po wyjęciu z pudełka bez dodatkowej konfiguracji. Alternatywnie można go użyć z composer.

 17
Author: John Slegers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-21 16:05:36

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;
}
W tym miejscu znajdziesz informacje na temat tego, co chcesz wiedzieć o GitHubie.]}
 16
Author: Paul Warelis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-12 01:23:11

Dla HTML5 , html5 lib został porzucony od lat. Jedyną biblioteką HTML5, którą mogę znaleźć z najnowszą aktualizacją i zapisami konserwacji, jest html5-php, która została właśnie wprowadzona do wersji beta 1.0 nieco ponad tydzień temu.

 16
Author: Reid Johnson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-28 17:43:39

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ą parsera XML.

 14
Author: CesarB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-15 22:24:15

Kolejną opcją, którą możesz wypróbować, jest QueryPath . Jest inspirowany jQuery, ale na serwerze w PHP i używany w Drupal .

 13
Author: Richard Le Poidevin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-31 22:47:49

XML_HTMLSax jest raczej stabilny - nawet jeśli nie jest już utrzymywany. Inną opcją może być przepuszczenie HTML przez HTML Tidy, a następnie przetworzenie go za pomocą standardowych narzędzi XML.

 11
Author: troelskn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-15 19:55:44

Framework Symfony ma pakiety, które mogą analizować HTML, i możesz użyć stylu CSS, aby wybrać DOMs zamiast XPath .

 11
Author: Tuong Le,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-31 22:49:29

Istnieje wiele sposobów przetwarzania HTML / XML DOM, z których większość została już wymieniona. Dlatego Nie będę sam ich wymieniać.

Chcę tylko dodać, że osobiście wolę używać rozszerzenia DOM i dlaczego:

  • iit optymalnie wykorzystuje przewagę wydajnościową podstawowego kodu C
  • jest to oo PHP (i pozwala mi go podklasować)
  • jest raczej niski poziom (co pozwala mi używać go jako nie nadęty podkład dla bardziej zaawansowanych zachowanie)
  • zapewnia dostęp do każdej części DOM (w przeciwieństwie do np. SimpleXml, który ignoruje niektóre z mniej znanych funkcji XML)
  • ma składnię używaną do indeksowania DOM, która jest podobna do składni używanej w natywnym Javascript.

I chociaż brakuje mi możliwości używania selektorów CSS dla DOMDocument, Istnieje dość prosty i wygodny sposób na dodanie tej funkcji: podklasowanie DOMDocument i dodanie metod podobnych do JS querySelectorAll i querySelector do podklasy.

Do parsowania selektory, polecam użycie bardzo minimalistycznego komponentu CssSelector Z frameworka Symfony . Ten komponent po prostu tłumaczy selektory CSS na selektory XPath, które można następnie wprowadzić do DOMXpath, Aby pobrać odpowiednią listę Nodelist.

Możesz następnie użyć tej (wciąż bardzo niskiego poziomu) podklasy jako podstawy dla klas bardziej wysokiego poziomu, przeznaczonych np. analizuj bardzo specyficzne typy XML lub dodaj więcej zachowań podobnych do jQuery.

Poniższy kod pochodzi prosto z mojej biblioteki Dom-Query i wykorzystuje technikę, którą opisałem.

Do analizy 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 parsowanie dokumentów XML za pomocą selektorów CSS przez twórcę Symfony, Fabiena Potenciera, o jego decyzji o utworzeniu komponentu CssSelector dla Symfony i o tym, jak z niego korzystać.

 10
Author: John Slegers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-15 16:02:29

Z FluidXML można odpytywać i iterować XML za pomocą selektorów XPath I CSS .

$doc = fluidxml('<html>...</html>');

$title = $doc->query('//head/title')[0]->nodeValue;

$doc->query('//body/p', 'div.active', '#bgId')
        ->each(function($i, $node) {
            // $node is a DOMNode.
            $tag   = $node->nodeName;
            $text  = $node->nodeValue;
            $class = $node->getAttribute('class');
        });

Https://github.com/servo-php/fluidxml

 9
Author: Daniele Orlando,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-07 16:44:44

Istnieje kilka powodów, aby nie analizować HTML za pomocą wyrażenia regularnego. Ale jeśli masz całkowitą kontrolę nad tym, co HTML zostanie wygenerowany, możesz to zrobić za pomocą prostego wyrażenia regularnego.

Powyżej jest to funkcja, która parsuje HTML za pomocą wyrażenia regularnego. Zauważ, że ta funkcja jest bardzo wrażliwa 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/")));
 7
Author: Daniel Loureiro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-28 17:45:41

JSON i tablica z XML w trzech liniach:

$xml = simplexml_load_string($xml_string);
$json = json_encode($xml);
$array = json_decode($json,TRUE);
Ta da!
 6
Author: Antonio Max,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-28 17:44:03

Stworzyłem bibliotekę o nazwie HTML5DOMDocument, która jest bezpłatnie dostępna pod adresem https://github.com/ivopetkov/html5-dom-document-php

Obsługuje również selektory zapytań, które myślę, że 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;
 2
Author: Ivo Petkov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-21 08:38:33

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 zwykle zajmuje mniej niż 1 sekundę, aby przetworzyć html offline.
Akceptuje również nieprawidłowy HTML lub brakujący cytat na atrybutach tagu.

 0
Author: StefansArya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-16 12:35:01