
Parsování HTML v PHP
Jak v PHP parsovat HTML stránku a získat z ní potřebná data.
V případě, že je potřeba získat z nějaké stránky data pro vlastní použití, bývá v ideálním případě k disposici obsah ve strojově čitelné podobě:
Ve formátu JSON.
-
Pro přímé vložení obsahu se používá oEmbed.
-
Existují i méně používané formáty jako CSV (jednotlivé položky jsou odděleny čárkami), SOAP (založený na XML) a podobně.
Není-li strojově čitelný formát k disposici, je nutné parsovat HTML.
Regulární výrazy
První možnost je požadovaná data vyzobat regulárními výrazy.
V PHP se k tomu používají funkce preg_match
nebo preg_match_all
.
Regulární výrazy je potřeba šít přesně na míru konkrétnímu zdrojovému kódu stahovaného webu. Vzhledem k tomu, že svou roli zde hraje každý znak, změna HTML kódu cílové stránky snadno způsobí nefunkčnost.
Získání obsahu značky
Pro ilustraci poslouží následující příklad pro získání titulku stránky:
$page = file_get_contents("http://example.com");
preg_match("/<title>(.*)<\/title>/i", $page, $matches);
echo $matches[1];
Nejprve se funkcí file_get_contents
stáhne obsah externí stránky, načež se funkcí preg_match
vybere obsah značky <title>
.
Řada lidí se regulárních výrazů bojí. Naštěstí existují další způsoby:
PHP DOM
V PHP existují funkce pro práci přímo s HTML DOMem. V takovém případě se ze získaného HTML řetězce nejprve sestaví DOM (Document Object Model) a nad ním jde potom používat metody typu getElement*
známé z JavaScriptu.
Jedná se o třídu DOMDocument.
Při použití této třídy je postup získávání obsahu trochu méně závislý na změnách zdrojového kódu. Už nejde o každý znak v HTML, ale o podobu výsledného DOMu.
Oproti JavaScriptu asi nejvíce chybí querySelector
umožňující vybírat HTML značky pomocí CSS selektorů.
Získat obsah značky <title>
pomocí PHP metod DOMu jde následovně:
$dokument = new DOMDocument();
@$dokument->loadHTMLFile('http://example.com');
$title = $dokument->getElementsByTagName('title');
echo $title->item(0)->nodeValue; // hodnota první položky
Externí stránku lze načíst přímo přes loadHTMLFile
.
Vypsání všech odkazů
Jednotlivé vybrané značky mají další metody, třeba getAttribute
, která umožňuje získat hodnotu HTML atributu.
Procházet kolekci elementů jde cyklem foreach
.
Následující příklad vypíše všechny odkazy na této stránce:
$dokument = new DOMDocument();
@$dokument->loadHTMLFile('http://jecas.cz/php-parsovani-html');
$odkazy = $dokument->getElementsByTagName('a');
foreach ($odkazy as $odkaz) {
echo "<li>" . $odkaz->getAttribute("href");
}
Vypsání HTML obsahu značky
Položky DOMu v PHP nemají vlastnost innerHTML
jako v JavaScriptu. Pro získání HTML kódu tak slouží metoda saveHTML
volaná nad DOMDocument
em – předává se jí požadovaný element:
$dokument->saveHTML($odkaz);
XPath
Nejsilnější možnosti pro vybírání obsahu nabízí XPath (v něčem je i mocnější než CSS selektory).
XPath se naroubuje na DOMDocument
:
$dokument = new DOMDocument();
@$dokument->loadHTMLFile('http://example.com');
$xpath = new DOMXPath($dokument);
Následně jde titulek stránky vybrat pomocí prostého:
echo $xpath->query('//title')->item(0)->nodeValue;
XPath vs. CSS
Pro rychlé pochopení, jak v XPath funguje výběr elementů, je ideální srovnání se selektory v CSS:
CSS | XPath |
---|---|
* | //* |
div | //div |
div h1 | //div//h1 |
div > h1 | //div/h1 |
div#id | //div[@id='id'] |
div.trida | //div[@class='trida'] |
div[title] | //div[@title] |
p:first-child | //p[1] |
h1 + p | //h1/following-sibling::p[1] |
Jak je vidět, libovolný potomek se značí //
, přímý potomek potom jen jedním /
, atributy se uvádějí do hranatých závorek se zavináčem.
Výběr podle třídy
Vybírání elementu podle třídy je při použití XPath odlišné oproti pravidlům CSS. V případě více přiřazených tříd se element nevybere – XPath vyžaduje přesnou shodu hodnoty atributu.
Chování blíže podobné CSS jde zajistit tímto zdlouhavým zápisem (vysvětlení):
//*[contains(concat(" ", normalize-space(@class), " "), " trida ")]
Při použití stručnějšího zápisu:
//*[contains(@class, 'trida')]
By se chybně zachytil i element s třídou jina-trida
.
Další možnosti XPathu jsou popsány v následujícím přehledu:
CSS selektory v PHP
Možnost používat v PHP přímo CSS selektory nabízí několik hotových knihoven. Je ale možné, že budou pomalejší než XPath.
Související články

Výpis náhodného textu
Jak na stránce náhodně vypsat obrázek, odkaz, reklamu, text nebo cokoliv jiného.

Instalace Apache, PHP a MySQL za 30 vteřin
Jak si ve Windows spustit vlastní Apache, PHP a MySQL na svém PC za půl minuty.

MySQL přes PDO
PDO je PHP rozhraní pro pohodlnější práci s SQL databásí. Jaké přináší výhody a jak ho používat.

Upload obrovských souborů v JS/PHP
Jak umožnit návštěvníkům nahrát soubory jako videa v řádech MB/GB s progress barem.