Haluan saada tori.fi sivustolta tietyllä hakusanalla linkit kaikkiin sivulla oleviin myynti-ilmoituksiin. Ongelmaksi muodostuu kuitenkin se, että jokaisella sivulla saattaa olla ensimmäisenä maksettu nostettu myynti-ilmoitus enkä halua saada sitä. Se on kuitenkin melko vaikea erottaa tavallisista ilmoituksista.
Tällä koodilla saan sivulla olevat linkit myynti-ilmoituksiin, mutta mukana tulee myös nostettu ilmoitus.
$tori = file_get_contents('http://www.tori.fi/koko_suomi/puhelimet_ja_tarvikkeet/puhelimet?ca=15&q=iPhone&cg=5010&c=5012&st=s&cp=apple&w=3&o=' . $page); preg_match_all('/\<a tabindex\="50" href\="(.+?)"/', $tori, $links); $links = array_unique($links[1]);
Maksetun myynti-ilmoituksen erottaa muista siten, että se alkaa esim
<div id="pp_item_31243054" class="item_row polepos_row">
kun tavallinen myynti-ilmoitus alkaa
<div id="item_31068741" class="item_row">
Niinpä kokeilin seuraavaa, mutta jostain syystä en saa tällä yhtään linkkiä
$tori = file_get_contents('http://www.tori.fi/koko_suomi/puhelimet_ja_tarvikkeet/puhelimet?ca=15&q=iPhone&cg=5010&c=5012&st=s&cp=apple&w=3&o=' . $page); preg_match_all('/id\="item.*?\<a tabindex\="50" href\="(.+?)"/', $tori, $links); $links = array_unique($links[1]);
Mikähän tuossa menee pieleen tai löytyisikö jokin toinen tapa, jolla saan halutut linkit sivulta?
Sain tämän koodin toimimaan halutulla tavalla. Katsoin ohjeita tältä sivulta ja sen mukaan muokkasin koodia. En ole aivan varma mikä tässä oli se ratkaiseva muutos niin, että tämä nyt toimii.
Toimiva koodi oli tällainen
$tori = file_get_contents('http://www.tori.fi/koko_suomi/puhelimet_ja_tarvikkeet/puhelimet?ca=15&q=iPhone&cg=5010&c=5012&st=s&cp=apple&w=3&o=' . $page); preg_match_all('/id=\"item.*\<a\stabindex=\"50\" href=\"(.+)\"/siU', $tori, $links); $links = array_unique($links[1]);
Ratkaiseva muutos on valitsin s, jolla saadaan piste ottamaan mukaan myös rivinvaihtoja. Suosittelen lausekkeen palauttamista muilta osin alkuperäiseen muotoon: i on turha, U vaikeuttaa lausekkeen ymmärtämistä, ja välilyönnin vaihto \s:ään on turha, jos sivun lähdekoodissa kuitenkin on se välilyönti.
Muistutuksena vielä, että merkkejä ", > ja = ei todellakaan tarvitse lausekkeessa escapettaa.
Kiitos vastauksesta. Muutin koodin muotoon
$tori = file_get_contents('http://www.tori.fi/koko_suomi/puhelimet_ja_tarvikkeet/puhelimet?ca=15&q=iPhone&cg=5010&c=5012&st=s&cp=apple&w=3&o=' . $page); preg_match_all('/id="item.+?<a tabindex="50" href="(.+?)"/s', $tori, $links); $links = array_unique($links[1]);
ja näyttäisi toimivan tällä hyvin.
Eikö <, > ja = ole kuitenkin erikoismerkkejä, joten mistä johtuu, ettei niitä tarvitse escapettaa?
AkeMake kirjoitti:
Eikö <, > ja = ole kuitenkin erikoismerkkejä, joten mistä johtuu, ettei niitä tarvitse escapettaa?
Ne ovat erikoismerkkejä vain tietyissä sulkurakenteissa: (?=x), (?<=x), (?<nimi>x). Myös näissä riittää pelkän kysymysmerkin escapetus, koska samalla muidenkin erityismerkitys häviää.
Vastaavasti hakasulkujen sisällä viiva (-) on erityismerkki mutta useimmat muut erityismerkit (kuten *+?.(){}) eivät.
Hauskaa triviatietoa: hakasulkujen sisällä viiva ei ole erikoismerkki, jos se on ensimmäinen tai viimeinen merkki. Myöskään avaava hakasulku ei ole erikoismerkki, eikä sulkeva hakasulku, jos se on ensimmäinen merkki.
Siispä regex /[][-]/
sisältää yhden merkkiluokan, joka hyväksyy jonkin seuraavista merkeistä: ]
[
-
No siinäpä olikin läjä minulle ihan uutta tietoa, jota ei löydy myöskään PHP-oppaan säännöllisten lausekkeiden osasta. Muutenkaan se osa, niin hyvä kuin onkin, ei tarjoa kovin kattavaa tietoa näistä erikoismerkeistä ja ainoastaan kommenteissa joku on antanut jonkinlaisen listan niistä. Olisiko tässä asia, jonka voisi päivittää oppaaseen?
Maksetuissa nostoissa ei muuten ole tuota polepos_row:ta. Ainoastaan paalupaikalle ostetuissa.
Eikös tämä olisi helpompaa jollain xpath tms. rakenteellisella lähestymistavalla? Ei tarvitsisi luoda SL
Se on tarkoituskin, ettei paalupaikalle nostettu ilmoitus tule useampaan kertaan, koska se löytyy myös alkuperäiseltä paikaltaan muiden ilmoitusten joukosta. Enkä muutenkaan tee tunnistusta tuolla polepos_row:lla vaan item:llä. Maksetussa ilmoituksessa on id="pp_item... kun tavallisessa on id="item...
Varmasti tämän toteuttamiseen löytyisi helpompiakin keinoja, mutta menen oman osaamiseni puitteissa. Tämä on se tapa, jolla osaan asian toteuttaa eikä nyt ole mielenkiintoa opiskella uusia tapoja.
Joo kannattaa se tuplanpoisto tehdä tuolla item_ tai pp_item_ jälkeen tulevan numeron perusteella. (Eli jos numero on jo kannassa, niin se on jo olemassa eli tupla) Ilmoituksen voi nostaa muullakin tavalla kuin tuolla paalupaikalla, eikä siihen silloin tule myöskään pp_ -etuliitettä.
Aihe on jo aika vanha, joten et voi enää vastata siihen.