Autor Zpráva
Acer1968
Profil
Dobrý den.

Jsem amatér, čili se omlouvám, pokud některé věci opíšu špatně. Potřebuji vyparsovat některé údaje z HTML kódu. Používám PHP Simple HTML DOM Parser. Pokud má tag nějaký signifikantní rys (přiřazené ID, třídu, atribut), pak si umím říct o jeho hodnotu (pro Vás triviální, pro mě vítězství). Ale problém je, že data na vstupu nejsou vždy úplně schodná, a tak nevím, jak si říct o město v následujícím příkladu:

<p itemprop="address" itemscope itemtype="http://schema.org/PostalAddress" class="bold adr">
<span itemprop="streetAddress">Krátká 1</span>
<br />
Kladno<br />
<span itemprop="addressLocality">Kladno</span>
<br />
<span itemprop="postalCode">272 01</span>
 Kladno 1<br />
</p>

Tady bych si sáhl pro hodnotu spanu s atributem "adressLocality". Ale bohužel ne vždy je tento span vyplněn a já si nedokážu vytáhnout to Kladno nad ním, nebo pod PSČ. Čili u HTML, jako je to následující, jsem mimo:

<p itemprop="address" itemscope itemtype="http://schema.org/PostalAddress" class="bold adr">
<span itemprop="streetAddress">Dlouhá 2</span>
<br />
Kladno<br />
<span itemprop="postalCode">272 01</span>
Kladno<br />
</p>

Já se koukal i na tu stránku http://schema.org/PostalAddress , ale tam se prostě předpokládá, že se použije tag i identifikátorem "adressLocality".

Mě totiž připadá, že ty dvě hodnoty Kladno v ukázce výše tak nějak leží MIMO ostatní tagy. Jasně, jsou součástí toho <p>, které je obaluje, ale nepodařilo se mi na ně přes Child nijak sáhnout. Ani traverzování třeba od "postalCode" se mi nedaří:

$mesto = $html->find('span[itemprop="postalCode"]')->outertext;

tedy nevede k cíli.

Poradí někdo?

Děkuji.
Petr Vavřinec
Kcko
Profil
Acer1968:
převést metodou plaintext na plaintext a poté explodnout "\n" do pole a máš tam hodnoty které potřebujes a dle nějaké logicky s tím naložíš?
Acer1968
Profil
Kcko:
Ahoj.
Díky za radu, rada dobrá, ale nepoužitelná. Já totiž tady v tom příkladě to řádkování udělal ručně, abyste se zbytečně dlouho neorientovali v tom html kódu. Čili originál html kód NEMÁ řádkování, je to prostě souvislá množina písmenek. Navíc má každá ta stránka, kde je právě jen jedna adresa, asi 60kB, takže mi připadá zbytečné zpracovávat složitě celou stránku (pokud by byla odřádkovaná) kvůli ulici, městu a psč, když tam jinak funguje pěkné cílení. I když, pravda, převést do plaintextu by šel jen ten tag <p>, ale jak říkám, není to na víc řádkách. Čili hledám metodu, jak vyzobnout text mezi dvěma <br />... Jenže <br /> není párový tag, tudíž asi nemá innertext :-(

Petr V.
Kcko
Profil
Když hodíš odkaz odkud to taháš a co přesně potřebuješ výstupem, můžu to zkusit.
Acer1968
Profil
Kcko:
HTML soubor je třeba tady:
http://simplephpparser.8u.cz/adresa_na_rozpad.htm

s kódem:
<html><head><meta http-equiv="Content-Type" content="text/html;charset=utf-8"></head><body><p itemprop="address" class="bold adr"><span itemprop="streetAddress">Masarykova 234</span><br />Hořovice<br /><span itemprop="postalCode">268 01</span>Hořovice<br /></p></body></html>

A script, kterým to zpracuji je:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Adresy</title>
</head>
<body>
<?php
include('simple_html_dom.php');
$adresa = "http://simplephpparser.8u.cz/adresa_na_rozpad.htm";
$htmlstranka=file_get_html($adresa);
// uložím si ulici a oddělím #
$vystup = $htmlstranka->find('span[itemprop="streetAddress"]',0)->innertext."#";
// připíšu/uložím si psč a oddělím #
$vystup .= $htmlstranka->find('span[itemprop="postalCode"]',0)->innertext.'#';
// chci uložit město a oddělit # - ALE tohle span[itemprop="postalCode" dole je špatně, to je to co řeším, nevím, jak se dostat k hodnotě textu obsahujícího město ležící za tagem <span itemprop="postalCode">268 01</span>
$vystup .= $htmlstranka->find('span[itemprop="postalCode"]',0)->innertext.'#'; 
echo "Vypisuji: ".$vystup."<hr />";
?>

A chci, aby z toho vylezlo:
Vypisuji: Masarykova 234#268 01#Hořovice#

Jenže mě zatím vylejzá:
Vypisuji: Masarykova 234#268 01#268 01#
protože tam v příkladu jsem nechal vyparsovat dvakrát PSČ, protože neumím vyparsovat to město...

Petr V.
Kcko
Profil
Hmm přes SimpleHtmlDom to nejde, protože to není ničím obaleno, nepůjde to odchytit / nejde traverzovat v DOMu. Takže co můžeš udělat: najít si koncovou značku <span itemprop="postalCode"> tj </span> od této značky se dostat na konec odstavce </p>
V tomto fragmentu je město, takže z toho přes strip_tags vyházet HTML a je to.
Acer1968
Profil
Kcko:
No tak nakonec jsem to vyřešil podle tvé rady následovně:

$mesto = $html->find('p[itemprop="address"]',0)->innertext;
$pieces = explode("</span>", $mesto);
$mesto = trim(strip_tags($pieces[max(array_keys($pieces))]));

Nechal jsem to rozpadnout podle tagu </span>, který je poslední přes textem města a za ním už nic není. Očistil a hotovo. Není to sice asi úplně správné řešení, ale na moje data to funguje, čili účel to splnilo.

Díky moc za pomoc. Každopádně je otázka, jestli to html je správně, když opravdu ty texty měst nebyly obaleny ničím. Respektive ony byly obaleny tím <p>. Takže jsem chvíli přemýšlel, že bych nahradil pomocí DOM replaceChild funkce všechny vnitřní tagy prázdným neexistujícím tagem a tím bych to <p> pročistil, ale to jsem nedokázal.

Petr V.

Vaše odpověď


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: