Miten saan php:llä haettua esim http://www.mbnet.fi sivun lähdekoodin vaikka muuttujaan $lähde
Toinen kysymys...
Miten saan etsittyä tuosta lähdekoodista kaikki www-linkkien osoitteet ja tallennettua vaikka taulukkoon
$linkki[1]
$linkki[2]
$linkki[3]
...
En hae välttämättä valmista koodia, mutta sekin kyllä kelpaa.
Kertokaapa millä hakusanoilla kannattaisi meennä php.net:tistä etsimään tietoa.
Tämä voi olla avuksi. Ei tarvinnut kovin kaukaa hakea.
Ei oikeen tuo kyseinen koodi toimi...
Kokeilkaapas allaolevassa osoitteessa.
http://tausta.com/uus/mese/koe.php
Ohjelmointiputkan etusivu...
Löydetyt e-mail osoitteet:
[2 kpl] ...
Löydetyt linkit:
[0 kpl]
Ensimmäinen onnistuu helposti file_get_contents-funktiolla, joka lukee sivun tiedot yhtenäiseen merkkijonoon. Jos käyttämäsi PHP-versio on sen verran vanha, ettei siinä ole kyseistä funktiota, niin voit käyttää file-funktiota, joka lukee sivun tiedot taulukkoon. Linkkien etsiminen onnistuu helpoiten sopivan säännöllisen lausekkeen avulla. Tässä tulee vielä molempiin kysymyksiin liittyvä esimerkki, joka näyttää kaikkien sivulla olevien linkkien osoitteet ja tekstit taulukossa.
<?php $sivu = file_get_contents("https://www.ohjelmointiputka.net/"); preg_match_all("/<a href=\"([^\"]+)\">([^<]*)<\\/a>/i", $sivu, $linkit); echo "<table><tr><td><b>osoite</b></td><td><b>teksti</b></td></tr>"; for ($i = 0; $i < count($linkit[0]); $i++) { echo "<tr><td>{$linkit[1][$i]}</td><td>{$linkit[2][$i]}</td></tr>"; } echo "</table>"; ?>
Koodin parsimisesta vielä...
Yritin napata <title>tämän tiedon tästä välistä</title>
Yritin näin...
preg_match_all("<title[^>][^<]/title>", $sivu, $title);
Yritin katsela php.netttiä mutta ei aivan mennyt jakeluun.
Tarkoittaako tuossa <title[^>]tästä eteenpäin otetaan merkit.
Ja lopetaan merkkijonoon [^<]/title>.
Mutta mitä tarvin tuonne väliin vielä.
Varoitan: en osaa regexpejä, joten korjatkoon joku, jos opastan väärin, mutta itse käyttäisin tuossa funktiota preg_match() jotakuinkin tällä lailla:
preg_match("/<title>([^<]+)<\\/title>/i",$sivu, $title);
Tämä tarkoittaa selkokielellä, että etsitään merkkijonoa "<title>". Sen jälkeen avataan sulkeet, jotta sulkeiden väliseen merkkijonoryhmään voidaan myöhemmin viitata. Sulkeiden välissä rajaamme merkkijonoa hakasulkeilla. Hakasulkeiden sisällä '^'-merkki on negaatio, eli tarkoittaa käytännössä sitä, että hyväksymme minkä tahansa merkin, paitsi '>'-merkkiä tähän ryhmään. '+'-merkki taas tarkoittaa, että merkkejä on löydyttävä vähintään yksi kappale. Kun törmätään '>'-merkkiin hypätään ryhmästä ulos ja tarkistetaan vielä, että ryhmän perästä löytyy '</title>' regexp-lauseet alkavat ja loppuvat aina kenoviivaan, jonka jälkeen voidaan vielä antaa lisämääreitä. 'i'-tarkoittaa case-insensitiveä. Jos kaikki ehdot täyttyivät, tagien välinen osa pitäisi löytyä $tile[1]-solusta.
Ja ihan sivuhuomautuksena: Minusta ainakin on kohteliasta kiittää avusta, Anttikin antoi sinulle valmiin koodin, mutta et edes vaivautunut kommentoimaan tomiko se.
ajv kirjoitti:
Ja ihan sivuhuomautuksena: Minusta ainakin on kohteliasta kiittää avusta, Anttikin antoi sinulle valmiin koodin, mutta et edes vaivautunut kommentoimaan tomiko se.
Joo kyllä koodi toimi hienosti ja sain muokattua omaan käyttöön paremmin sopivaksi.
Kiitokset vain kaikille vaivautuneille. (Ei aina huomaa juuri heränneenä.)
Vielä yksi ongelma tuli eteen...
$sivu // nimiseen muuttujaan ladataan kyseisen sivun sisältö...
Miten tuosta saisi kaikki < ja > merkit ja välissä olevan tekstin pois.
Olisko ideaa:
$sivu = str_replace("<", "/*", $sivu); $sivu = str_replace(">", "*/", $sivu);
Elikkä muuttas kommenteiksi nuo kaikki < ja > merkkien välissä oleva.
Olisi varmaan olemassa parempikin keino...
Kyllä, siihen olisi parempikin keino, nimittäin strip_tags.
http://php.ohjelmointiputka.net/?strip_tags
/* */ Ei muuten ole HTML:ssä kommentti. HTML:ssä on <!-- -->
Strip tags vaan heivaakin sitten kaiken sieltä välistäkin muistaakseni? käytä mielummin htmlspecialchars(); :)
Ei vaan strip tags poistaa nimensä mukaisesti tagit, eli
<?php $teksti = "<p><b><i>Juu</i> ei</b> ehkä</p>"; echo strip_tags($text); // Tulostaa: Juu ei ehkä ?>
Ajv, kiitos selkokielisestä regexp esimerkistä. Itsekin tuota Antin hyvää esimerkkiä kokeilin, huomasin tosin että se ota linkkejä joissa on jotain määreitä, esim tätä se ei ota ollenkaan: <a href="/testi" class="testi">Testi</a>
Jonkinlaisen purkkaversion sain tehtyä Ajv:n esimerkin pohjalta, kun olen vieläkin ihan surkea regexpien teossa:
<?php $sivu = file_get_contents($_GET['osoite']); preg_match_all("/<a href=\"([^\"]+)\"[^<]*>([^<]*)<\\/a>/i", $sivu, $linkit); echo "<table><tr><td><b>osoite</b></td><td><b>teksti</b></td></tr>"; for ($i = 0; $i < count($linkit[0]); $i++) { echo "<tr><td>{$linkit[1][$i]}</td><td>{$linkit[2][$i]}</td></tr>"; } echo "</table>"; ?>
Siis tuota yhtä regexpiä vain on muutettu. Vielähän tuossa on viilaamista, esim vaikka näyttämään sivuston sisäiset urlit oikein.
Edit: Tuo ei nyt näemmä enään löydä linkkejä ilman jotain class tai vastaavaa määrettä. Damn.
Noin, nyt sain korjattua. Yksi + piti vaihtaa *.
Tässä on parannettu lauseke, jossa muita attribuutteja saa olla ja href voi olla missä kohdassa tahansa:
"/<a[^>]*href=\"([^\"]+)\"[^>]*>([^<]*)<\\/a>/i"
Ainoa lisäys on siis nämä määritykset, jotka tarkoittavat mitä tahansa tekstinpätkää, jossa ei ole >-merkkiä:
"[^>]*"
Säännöllisistä lausekkeista: https://www.ohjelmointiputka.net/oppaat/opas.
Kiitos Antti.
Mbnetissä törmäsin vielä sellaiseen ongelmaan että sielä on seuraavanlaisia linkkejä:
<a HREF="/jutut/uutiset/?from=etusivu#U1729"><!-- -->Eurooppa aikoo kytätä nettiterroristeja </a>
Eli tuon regexpin pitäisi päättyä vasta </a> määreeseen eikä < määreeseen. Pitää vielä viilata.
Tässä kun ei muutakaan tekemistä ole niin tuota värkkäilen. Tilannetta voi seurata täältä:
http://jts.dy.fi/temp/tutkija/antin.php?osoite=http://www.ohjelmointiputka.net
Edit
Putkaan ehdottomasti url-tagit! Ne toimivat kaikkialla muuallakin!
Aihe on jo aika vanha, joten et voi enää vastata siihen.