Autor | Zpráva | ||
---|---|---|---|
Milkys Profil |
#1 · Zasláno: 25. 3. 2014, 17:38:00
Pěkné odpoledne dámy a pánové,
testuji níže uvedený kod. Měl by vypsat url a popis z vyhledávače seznam.cz. Je funkční jen do té doby, dokud se v řetězci nevyskytuje zbozi.cz ap. To potom sežere i první url s popisem, která následuje po této upoutávce na zbozi.cz a to je pro mně nežádoucí. Záměrně jsem řetězec $str nevložil, aby to nebylo nepřehledné. Dá se získat ze zdrojáku ve vyhledávači. Prosím ví někdo kde dělám chybu? Předem děkuji. $str = ''; // zde bude řetězec začínající od první (včetně) <h3> až do konce stránky. Bez sklik reklam. $reg = '<h3> <a href="(.*?)".*?>(.*?)</a> </h3> <div class="description.*?>(.*?)</div>'; preg_match_all("~$reg~", $str, $matches); $urlList = $matches[1]; print_r($urlList); //pro kontrolu vypíše pole adres |
||
Tori Profil |
#2 · Zasláno: 25. 3. 2014, 17:45:58
IMHO by stačilo upravit první tři části v závorkách, aby nehledaly jakýkoli znak, ale jakýkoli znak kromě
> .
|
||
TomasJ Profil |
Milkys:
Přesně jak píše Tori, ale s malou úpravou. Texty v uvozovkách aby hledaly vše kromě uvozovek atribut="([^"]*)"
Další věc je <div class="description".*?>(.*?)</div> vyznačená uvozovka chybí.
EDIT: Přeškrtnuté je to proto, že v description se vyskytuje i tag <b> na vyznačení shodných hledaných výrazů. To znamená, že je potřeba nejdřív všemu v description buď odstranit tagy a nebo převést < a > na entity. (< = < | > = >).
Dalo by se také napsat regulár na vynechání <b></b> .
|
||
Milkys Profil |
#4 · Zasláno: 25. 3. 2014, 18:01:38 · Upravil/a: Milkys
TomasJ, Tori:
Děkuji Vám oběma. Vyzkouším, reguláry neovládám, učím se, pokus - omyl :). Takže vážení asi to pěkně kopu. Poslední verze včetně pokusu o odstranění tučných tagů je: $reg = '<h3> <a href="([^"]*)".*?>([^>]*)</a> </h3> <div class="description.*?">([^<(/?)b>]*)</div>'; |
||
TomasJ Profil |
Milkys:
To, co je uzavřené v [ ] jsou znaky. Nelze do toho uzavřít celé slovo, protože vše je chápáno jako jednotlivé znaky samostatně na sebe nenavazující.
Doporučuji přečíst si pár článků o regulárech. Třeba rovnou zde www.root.cz/clanky/regularni-vyrazy-1/ a nebo zde http://www.regularnivyrazy.info/regularni-vyrazy-zaklady.html |
||
Tori Profil |
Milkys:
Zkuste to brát postupně, nejdřív najít všechny odkazy + popisy, až potom popisy odtučňovat. :) |
||
Milkys Profil |
#7 · Zasláno: 25. 3. 2014, 19:27:41
TomasJ:
to mám otevřené a z toho jsem čerpal na tu část na odstranění <b> a </b>. Nicméně mi ty tagy v popisu nevadí. A pokud by mi vadily existuje strip_tags. Malinko jsem postoupil. Zjistil jsem, že toto vypisuje url i za zbozi.cz, ovšem nezískám popis $reg = '<h3> <a href="([^"]*)".*?>([^>]*)</a>'; a to umí i ten můj původní kod. $reg = '<h3> <a href="(.*?)".*?>(.*?)</a>'; |
||
TomasJ Profil |
Milkys:
Z jaké URL adresy čerpáte výsledky? Abych přesně věděl, co vyzkoušet. Tak mi to nedalo, zkusil jsem taky něco napsat a následně vyhledat. Funguje to v pohodě. Problém byl v metaznacích nacházejících se v hledaných hodnotách. Takže ať se netrápíte: <?php function array_stripSlashes($array){ foreach($array as $i => $data){ if(is_array($data)) $array[$i] = array_stripSlashes($data); else $array[$i] = stripslashes($data); } return $array; } $get = file_get_contents("http://search.seznam.cz/?q=regularni+vyrazy"); $get = preg_quote(substr($get,strpos($get, '<h3> <a href="'))); $lt = '\\\<'; $gt = '\\\>'; $eq = '\\\='; $reg = "{$lt}h3{$gt} {$lt}a href{$eq}\"([^\"]*)\"[^>]*{$gt}(.*?){$lt}/a{$gt} {$lt}/h3{$gt} {$lt}div class{$eq}\"description\"[^>]*{$gt}(.*?){$lt}/div{$gt}"; preg_match_all("~$reg~",$get,$match); var_dump(array_stripSlashes($match)); ?> |
||
Milkys Profil |
#9 · Zasláno: 25. 3. 2014, 20:47:02
TomasJ:
q=bazény $str = řetězec začíná: <h3> <a href="1. pozice odkaz" title="Přejít na: 1. pozice odkaz" data-d..... a končí: ht"> © 1996–2014 Seznam.cz, a.s. </div> <img src="i.imedia.cz/miss?zoneId=seznam.search.hits&collocation=baz%C3%A9ny&referer=search.seznam.cz&count=1&r=cLuyQ2NIwmrapWi4nPC2" class="blind" alt="" height="1" width="1"> </div> |
||
TomasJ Profil |
Milkys:
urlencode Mně to funguje úplně normálně. Ale myslím, že bude lepší projet to XML parserem. Nachází se tam totiž pár položek, které mají jinou strukturu. |
||
Milkys Profil |
#11 · Zasláno: 25. 3. 2014, 21:16:34
TomasJ:
děkuji funguje. Už jen ze zdrojáku vycucám url zvlášť a popis zvlášť. To jsou 2 věci, které potřebuji. To už bude brnkačka. Ještě jednou děkuji za ochotu vyřešit problém. |
||
TomasJ Profil |
Milkys:
Pokud používáte výše psaný kód, například na dotaz "regularni vyrazy" vám seznam v prohlížeči vypíše 11 výsledku a v kódu jen 9. Chybí tam položka z interval.cz a matematika.cz (tak nějak to bylo). |
||
Milkys Profil |
TomasJ:
nepoužívám. Zjistil jsem, že jsem v podstatě na začátku. V předešlým příspěvku jsem se nechal unést. Asi jsem to na začátku špatně vysvětlil. Toto mi vyřízne řetězec, který je podobný tomu Vašemu. $get = file_get_contents("http://search.seznam.cz/?q=bazény"); $pattern = '<div class="text" id="modText.*?(.*)</div>'; if (preg_match("~$pattern~is", $get, $matches)) { if (!empty($matches[1])) { $str = $matches[1]; } } echo $str; S řetězcem $str dále pracuji viz. příspěvek #1 $reg = '<h3> <a href="(.*?)".*?>(.*?)</a> </h3> <div class="description".*?>(.*?)</div>'; preg_match_all("~$reg~", $str, $matches); $urlList = $matches[1]; // $matches[3] jsou popisy print_r($urlList); //pro kontrolu vypíše pole adres Toto všechno fachčí, jen mi to vždycky sežere i tu url a popis, která následuje po položkách zbozi.cz. Chápeme se? |
||
TomasJ Profil |
Milkys:
$pattern = '<div class="text" id="modText.*?(.*?)</div>'; ?To je asi blbost, ukončí se to moc brzo. Dál už jinak nevím, řešil bych to xml parserem. |
||
Milkys Profil |
TomasJ:
? nepomohl.
Nepomohla ani změna $reg: $reg = '<h3> <a href="([^"]*)"[^>]*>(.*?)</a> </h3> <div class="description"[^>]*>(.*?)</div>'; TomasJ: nic se neděje, nejde o život :). Třeba se objeví Kajman - ten už mi párkrát vytáh trn z paty nebo někdo podobný. Snaha byla děkuji za ochotu. Každopádně pokud to vyřeším dám to sem. Třeba se to někomu také hodí. TomasJ: Zrada je až v proměnné $reg. Do toho místa je vše ok. Ještě mě napadlo: zbozi má třídu hint: <div class="modCont hint zbozi"> <div class="modCont result cr".... Takže kdyby šlo nějak znegovat class hint. Něco jako: Pokud je tam class hint tak continue na další nejbližší třídu modCont. |
||
Tori Profil |
S uvedeným vyhledáváním mi fungovalo např. tohle:
$get = file_get_contents("http://search.seznam.cz/?q=bazény"); preg_match_all('~<div class="modCont result .+?</div>\s*<script>\s*JAK\.Fulltext\.ResultScreenshotResize~', $get, $matches); $results = array(); foreach ($matches[0] as $item) { if (preg_match('~<h3>\s*<a href="(.+?)" [^>]+? data-dot="title">(.+?)</a>.+?<div class="description" data-dot="description">(.+?)</div>~', $item, $m)) { $results[] = array( 'url' => $m[1], 'title' => html_entity_decode(strip_tags($m[2]), ENT_COMPAT, 'UTF-8'), 'description' => html_entity_decode(strip_tags(trim($m[2])), ENT_COMPAT, 'UTF-8'), ); } } var_dump($results); |
||
TomasJ Profil |
Milkys:
Tak regulár se trošku rozšířil, pořádně jsem koukl na strukturu a je to tak, hint má v class jen zboží a wikipedie. Na závěr jsem přidal funkci assocArray na poskládání adres k popisům.
Je možno zadat $k1 (adresa) a $k2 (popis) nebo je vynechat a nastaví se jim defaultně 0 a 1.
Takže tady je výsledek, který už je správný: <?php function array_stripslashes($array){ foreach($array as $i => $data){ if(is_array($data)) $array[$i] = array_stripSlashes($data); else $array[$i] = stripslashes($data); } return $array; } function assocArray($a1,$a2,$k1=0,$k2=1){ $r_array = Array(); $ca1 = count($a1); $ca2 = count($a2); $big_arr = $ca1 > $ca2 ? $ca1 : $ca2; for($i=0; $i<$big_arr; $i++){ if(isset($a1[$i])) $r_array[$i][$k1] = $a1[$i]; if(isset($a2[$i])) $r_array[$i][$k2] = $a2[$i]; } return $r_array; } $get = file_get_contents("http://search.seznam.cz/?q=bazeny"); $get = preg_quote($get); $lt = "\\\<"; $gt = "\\\>"; $eq = "\\\="; $reg = "{$lt}div class{$eq}\"modCont result[^\"]*\"[^>]*{$gt}.*?{$lt}div class{$eq}\"text\"[^>]*{$gt} ". "{$lt}h3{$gt} {$lt}a href{$eq}\"([^\"]*)\"[^>]*{$gt}.*?{$lt}/a{$gt} {$lt}/h3{$gt} ". "{$lt}div class{$eq}\"description\"[^>]*{$gt}(.*?){$lt}/div{$gt}"; preg_match_all("~$reg~",$get,$match); $match = array_stripslashes($match); $result = assocArray($match[1],$match[2],"url","popis"); var_dump($result); ?> Regulár poněkud dlouhý, ale musel jsem hodit quote kvůli tečkám a všelijakým metaznakům v popisech a url. Je třeba ještě ošetřit, pokud to nenajde nic, nebo nenajde adresy / popisy. Tori mezitím přidala asi lepší funkci, já se nechal asi moc unést :) Ještě dodám: Pro parsování zdroje XML parserem je v něm moc bordel. I po vhodném escapování všech entit mi parser psal chybu "not well-formed", takže by tam nejspíš musel zasahovat regulární výraz. |
||
Milkys Profil |
#18 · Zasláno: 26. 3. 2014, 09:11:30
Oběma strašně moc děkuji. Velice rád to oplatím pokud budu mít tu možnost.
Prosím příště nevykat :), nepřipadám si, že bych měl věk na vykání (45). Prosím od všech na foru o tykání. Každý je starý tak jak se cítí a já se cítím jak teenager :). Tori To tvé funguje přesně jak potřebuji. Jen kosmetická úprava: na ř. 9 má být prvek pole 3. Jinak 100 bodov. TomasJ: netestoval jsem - nebylo už potřeba. |
||
Časová prodleva: 10 let
|
0