Článek v rubrikách:

»PHP
»XML
»HTML

Parsování HTML pomocí DOM, kódování stránky windows-1250, ISO-8859-2 a další.

Parsovat české html stránky pomocí XPATH a DOMDOCUMENTu není žádná sranda. Trápil jsem se s tím hodně dlouho.


Zkuste si někdy parsovat html stránku s kódováním windows-1250 nebo jiným než ISO-8859-1. Za použití DOMDocumentu je to práce na dlouhé večery.

Jestli jsem něco přehlédl budu rád, když mi to někdo vysvětlí. Nicméně něco je špatně a nepodařilo se mne to standardní cestou rozchodit.

Základní věc je, že DOM interně pracuje v UTF-8, xpath pracuje také v UTF-8, výsledek, který ovšem získáte z parsování je v původním kódování. Tedy jakákoli další práce je v podstatě nemožná.

Pomocí funkce loadHTML se DOM pokusí detekovat o jaké kódování se jedná, to se snaží zjistit z tagu <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2" />, nejen že další práce s DOM je nespolehlivá (vytáhutá data z dom stromu jsou neurčitého kódování) ona není spolehlivá ani ta detekce. Někdy prostě nefunguje. V takovém případě dojde k načtení textu v kódování ISO-8859-1 a jeho převední do UTF-8, což kompletně stránky rozhodí.

Přes veškeré snahy se mi podařilo uskutečnit pouze tento plán:

  1. detekce vstupního kódování, parsování tagu meta pomocí regulárních výrazů,
  2. pomocí ICONV převod na kódování UTF-8 s parametrem //IGNORE,
  3. odstranění případného tagu <?xml ... ?> pomocí regulárních výrazů,
  4. nahrazení meta tagu s informací charset za <meta http-equiv="content-type" content="text/html; charset=utf-8" /> pomocí regulárních výrazů,
  5. teď jsme převedli html stránku do kódování UTF-8, což ještě musím DOMDocumentu oznámit takto @$dom->loadHTML('<?xml encoding="UTF-8">' . $html);

Nyní se teprve mohu spolehnout na výstup, který pomocí xpath získám a mohu uložit třeba do databáze.

Máte někdo jednodušší workaround?