Jak získat data z libovolné webové stránky pomocí PHP Simple HTML DOM Parser

Občas by člověk potřeboval získat data z nějaké jiné webové stránky, ke které nemá přístup. Např. aktuální kurzy, teploty … nebo jiná podobná data, která nejsou jinak přístupná. Jsou pouze někde už zobrazená, existují tedy v HTML kódu stránky. K jejich nalezení a získání poslouží právě knihovna simplehtmldom.

Dostal jsem se k zajímavému projektu – geolog p. Mucha měl na svých stránkách zobrazená zajímavá místa, která navštívil. Každé místo mělo na své stránce uvedené souřadnice, ale jako součást běžného textu. Každé takové místo patřilo do nějaké lokality. Mým úkolem bylo na stránkách lokalit zobrazit mapu (pomocí Seznam map) s jednotlivými místy.

Potřeboval jsem tedy

  1. Získat potřebná data (viz. tento návod)
  2. Zobrazit je jako mapu s označením jednotlivých míst

Konečný výsledek vypadá takto:

33 Výsledná mapa

https://www.geologie-astronomie.cz/Geologicke-lokality/Karlovarsko-a-za…

Jak získat strojová data

K zobrazení mapových bodu jsem potřeboval znát jejich souřadnici. Pro zobrazení různých značek – červené v aktuální lokaci, ostatní šedé – jsem potřeboval znát lokalitu dané souřadnice. Po kliknutí na bod se ukáže jeho jméno, obrázek a odkaz na detailní stránku.

Takže moje strojová data potřebovala obsahovat:

  • Souřadnice x (49°59'50.519"N)
  • Souřadnice y (12°37'12.477"E)
  • Strojové jméno lokace (Karlovarsko-a-zapadni-Cechy)
  • Jméno místa (Kynžvartský kámen)
  • URL obrázku
  • Link na detailní stránku

33Detail místa
Detail místa

Vzhledem k tomu, že jsem i na mapě jednotlivé lokace zobrazoval všechny značky, potřeboval jsem jeden velký soubor (pole) s informacemi o všech místech. Bohužel jsem neměl přístup k plnému CMS či databázi, a stejně nějaké údaje (např. souřadnice) se vkládaly přímo do běžného textu stránky. Takže sem je potřeboval nějak „vysosat“.

33simplehtmldom Quick start
simplehtmldom Quick start

Získání strojových dat

Začal jsem vytvářet jednoduchý PHP skript. Tam jsem si definoval pole jednotlivých lokalit, a to podle jejich URL.

Takže $lokace_all = array('Plzensko', 'Karlovarsko-a-zapadni-Cechy', ...

Tímto polem jsem procházel v cyklu a načítal HTML jednotlivých lokací:

$lokace_url = 'https://www.geologie-astronomie.cz/Geologicke-lokality/' . $lokace;$html = file_get_html($lokace_url);

file_get_html() je základní funkce simplehtmldom, která načte DOM daného zdroje, v mém případě konkrétní lokace, kde jsem hledal potřebné údaje. Po prozkoumání kódu jsem se zaměřil na hledání CSS třídy photo_gal_heading.

33Získání informací o místě

Z tagu <a> získám link detailní stránky místa, z tagu <img> zase link na obrázek a jméno místa. Spolu s tím si i uložím informaci o jménu dané lokace.
Takovýchto míst je v každé lokaci několik. Takže všechny místa – znám jejich link – potřebuju opět načíst a z jejich HTML kódu získat tentokráte souřadnice. Na to už mi přišlo zbytečné volat opět DOM, vystačil jsem si s běžnou PHP funkcí file_get_contents(), která vrátí HTML kód jako jeden velký řetězec. Tam jsem hledal řetězce jako '49°' nebo '50°' pro zeměpisnou šířku, resp. '12°' - '17°' pro zeměpisnou délku.

33Souřadnice

Celé výsledné pole jsem potom uložit jako JSON řetězec.

Takhle nějak vypadá příslušná část kódu:

33PHP kód

A výsledný JSON (výstup json_encode()):

33JSON

Optimalizace

Ukázalo se, že takovýto skript, zpracovávající desítky míst (tedy desítky volání file_get_contents()) dohromady s devíti voláními file_get_html() trvá poměrně dlouho, cca 10 sekund. To v reálném fungování znamenalo zbytečný prostoj. Vzhledem k tomu, že v tomto konkrétním případě nepotřebujeme získávat 100% aktuální data (místa se nemění/nevytváří často), stačí tento skript volat pomocí cronu třeba jednou denně, a výstup si ukládat do souboru.

Závěr

V tomto návodu jsem ukázal jednoduchý příklad užití knihovny “PHP Simple HTML DOM Parser” pro získání dat z HTML souboru. Jeho možnosti můžete rychle prozkoumat nahlédnutím do jeho manuálu https://simplehtmldom.sourceforge.io/manual.htm.

Takto získaná data jsem následně zobrazil pomocí seznamáckých map - viz. Jak zobrazit vlastní body a značky na turistické mapě od Seznamu?.