Gå til innhold

hvordan lage en php-crawler?


Anbefalte innlegg

Heisann!

 

Sitter å vurderer å lage en crawler/spider-basert søkemotor.. :)

Denne skal søke hele "www" etter websider, fetche tittel, beskrivelse (meta desc) og selv url-en.

 

Dette lar seg gjøre med file_get_contents, kobinert med preg_match (_all).. Ikke at jeg er noen spesialist på regex, og preg_match_all er nytt for meg.

 

All data må nødvendigvis lagres i en (mysql) database, med informasjon som er mottat fra preg_match, og hvilket hopp/nivå den er på?

 

Fikk satt ihop en regex som fungerer for å fetche lenker... :)

 $start = "http://www.hardware.no";
 $page  = file_get_contents($start);
 $stripped = strip_tags($page, "<a>");

 header("Content-type: text/plain");
 preg_match_all("/<a(?:[^>]*)href=\"([^\"]*)\"(?:[^>]*)>(?:[^<]*)<\/a>/is", $stripped, $matches, PREG_PATTERN_ORDER);

 print_r($matches);

I andre del så finner en "clean" lenker, altså det som er inni href-en. Dette virket som en god måte å gå frem på. Selv bare på første siden til hw, så fant jeg 300+ lenker (=

 

 

håper noen er lysten på å hjelpe til :)

Endret av tROOP4H
Lenke til kommentar
Videoannonse
Annonse

Heisann!

 

Sitter å vurderer å lage en søkemotor, på hobbybasis.. :)

Denne skal søke hele "www" etter websider, fetche tittel, beskrivelse (meta desc) og selv url-en.

 

Dette lar seg gjøre med file_get_contents, kobinert med preg_match (_all).. Ikke at jeg er noen spesialist på regex, og preg_match_all er nytt for meg.

 

Det blir nødvendig med en begrensning på f.eks 3 steg inn per side, om det eksisterer så mange hopp.

Eks:

> webside.no (fetch alle linker, hopp 1)

> forum (hopp 2)

> tråd (hop 3)

 

Deretter så skal den tilbake til nivå 2, gå inn i neste lenke, nivå 1 neste lenke? etc

 

Må kansje ha en variabel som sjekker om linken fører til en ny side, slik at den da nulstiller seg (hopp/nivå)?

 

Er veldig usikker på hvordan jeg skal oppnå dette.. Den skal bevege seg inn i alle nye sider, så fort den er ferdig med å scanne 1 side.

 

All data må nødvendigvis lagres i en (mysql) database, med informasjon som er mottat fra preg_match, og hvilket hopp/nivå den er på?

 

Fikk satt ihop en regex som fungerer for å fetche lenker... :)

 $start = "http://www.hardware.no";
 $page  = file_get_contents($start);
 $stripped = strip_tags($page, "<a>");

 header("Content-type: text/plain");
 preg_match_all("/<a(?:[^>]*)href=\"([^\"]*)\"(?:[^>]*)>(?:[^<]*)<\/a>/is", $stripped, $matches, PREG_PATTERN_ORDER);

 print_r($matches);

I andre del så finner en "clean" lenker, altså det som er inni href-en. Dette virket som en god måte å gå frem på. Selv bare på første siden til hw, så fant jeg 300+ lenker (=

 

 

håper noen er lysten på å hjelpe til :)

 

Vil nå egentlig påstå at du allerede har et bra utgangspunkt siden du har klart å fetche 300 linker på en side. Så jeg ville bare hivet alle linker som var ulik inn i en database og laget en for-loop som tok ut en og en link fra databasen. For hver link du tar ut av databasen crawler du har gjennom den gitte linken som sikkert gir noen ny linker som du igjen slenger inn i databasen. :w00t:

 

Edit: Samtidig så kan du jo slenge inn nøkkelordene fra siden. Så får man søkeresultat når man søker etter et ord eller en side =)

Endret av Nickless
Lenke til kommentar

Dette er slett ingen perfekt kode, og er vel langt i fra mål...

Benytter meg av count, for å telle radene i preg_match_all, men opplever noe underlig, veldig underlig vil jeg si!

 

Den teller ikke med den siste raden... Finner 10 lenker, men den påstår at jeg bare finner 9...

har testet på andre klomsemåter å fått til å funnet 10 lenker.. :o

 

 

<?php

set_time_limit(87500);

function getPageTitle($url) {
       $page  = file_get_contents($url);
       preg_match("/<title>(.*)<\/title>/imsU", $page, $title);
       return $title[1];
}

function getPageDesc($url) {
       $page  = file_get_contents($url);
       preg_match("/<meta\s+name=\s*[\"\']?description\s*[\"\']? content=[\"\'](.*)[\'\"]/imsU", $page, $desc);
       return $desc[1];
}

function shuffleIt($point) {
       $sql .= "SELECT * FROM ".PREFIX."links ORDER BY `fragle_id` ASC LIMIT $point,1";
       return ($sql);
}

function getDatabase($point) {
       $sql      = shuffleIt($point);
       $result   = mysql_query($sql);
       while ($r = mysql_fetch_array($result)) {
           $url .= $r['fragle_url'];
       }
       return($url);
}

function makeGoodURL($URL) {
if (substr($URL, -1) != "/") {
   $URL_fix = $URL;
} else {
   $URL_fix = substr($URL, 0, -1);
}

if (substr($URL_fix, 0, 7) != "http://") {$URL_done = "http://".$URL_fix;} 
else {$URL_done = $URL_fix;}

     return $URL_done;
}

//Kan skape evig loop ved: for($crawl=0; $crawl > -1; $crawl++) {
for($crawl=0; $crawl < 10; $crawl++) { //antall fetch fra databasen



 $start = getDatabase($crawl);
 $page  = file_get_contents($start);
 $stripped = strip_tags($page, "<a>");

 preg_match_all("/<a\s+href\s*=\s*[\"\']?http:\/\/([^\s\"\']+)[\"\'\s]+/ims", $stripped, $matches, PREG_PATTERN_ORDER);

 $rows = count($matches[$crawl]);  

 for($i=0; $i < $rows; $i++) {

   $newstart = makeGoodURL($matches[1][$i]);
   $title    = getPageTitle($newstart);
   $desc     = getPageDesc($newstart);
   $date     = time();
   //echo $newstart."<br />";
   if($newstart != "") {
     $rex = mysql_query("SELECT * FROM ".PREFIX."links WHERE fragle_url='$newstart'");
     if (mysql_num_rows($rex) == 0) {
        mysql_query('INSERT INTO '.PREFIX.'links (fragle_url, fragle_title, fragle_desc, fragle_last_crawl) VALUES ("'.$newstart.'", "'.$title.'", "'.$desc.'", "'.$date.'")') or die(mysql_error());
     }
   }
 }
}

?>

 

Problematisk...

Endret av tROOP4H
Lenke til kommentar

Problem med at den stopper opp etter den har lagt inn rundt 100 filer i databasen er løst ved å sette:

-> set_time_limit(140);

 

Og php header refresh 60 sek etter at den har stoppet.

 

Slik at den driver på i litt over 2 minutter, får pause i 1 minutt. Til nå har jeg (30 min) samlet 1000 rader fra verden med webside info, og dette skjer på en liten LAMPP-server med 700mb ram og 2.6GHz CPU, gikk slett ikke verst.. :) Men, den kresher vel før eller siden, mysql sluker ram, men tenker den klarer 10k+ rader med så lite info, bare de ikke dras ut samtidig :D

 

 

Dette var en god crawler til å bare være bygd opp av noen 10-talls linjer med kode.

Skal utvikle den vidre, og sette opp databaser med fulltext-search. og muligens legge alt inn på server-clusteret mitt, slik at jeg kan vireklig få benyttet meg av morsomhetene :)

 

 

Samt så må jeg spøre om det er noen annen måte jeg burde kalle til databasen på..?

Måten jeg gjør det på tror jeg ikke er "heeeelt korrekt", se LIMIT, og rand() :p

 

Dette vare bare metoden jeg brukte for å få testet hele scriptet, men jeg trenger at den lister på normalt vis, kjører en etter en tabell... Så må jeg finne en naturlig måte å sette den til å gå gjennom de tabellene som er eldre en xxxxx (unixtime)-> 7 dager --> 87000*7 sekunder (ca 7 dager).

 

function shuffleIt($point) {
       $sql .= "SELECT * FROM ".PREFIX."links ORDER BY rand() LIMIT $point,1";
       return ($sql);
}

Endret av tROOP4H
Lenke til kommentar

Jeg må modifisere en del her, slik at jeg kan exec fra kommandolinja. Scriptet selv vil kreve for mye resurser i lengden, men om jeg eller noen der ute kan hjelpe meg med å sette inn en sleep(80), så hadde jeg sluppet å kjøre den i browseren, med en ekstra fane konstant oppe.. :)

Lenke til kommentar

Jeg må modifisere en del her, slik at jeg kan exec fra kommandolinja. Scriptet selv vil kreve for mye resurser i lengden, men om jeg eller noen der ute kan hjelpe meg med å sette inn en sleep(80), så hadde jeg sluppet å kjøre den i browseren, med en ekstra fane konstant oppe.. :)

 

Hvis du sitter i linux eller har cronjob tilgjengelig kan du bare skrive:

 

php Eksempel.php

Lenke til kommentar

Hehe, klarer å starte scriptet fra kommandolinja wink.gif Det er ikke et problem. Buuut eventually... Så vil scriptet ta kvelden, om ikke hele serveren bare gjør det. Det trenger å stoppes fra tid til annen for å kunne få seg en pause. Det sluker tross alt resurser. Det må kunne kjøre i toppen noen minutter. For å så få ett minutt pause. Og jeg har selv ingen anelse på hvordan jeg skal gjøre dette på en handy måte.

 

Akkurat nå, så har jeg "meta refresh" satt til 60 sekunder øverst i headeren, denne starter ikke å gå da scriptet bare laster å laster. Defor har jeg kombinert den med set_time_limit(120);, så når tidsgrensen scriptet kan bruke er over, og 60 sekunder er gått, så vil fanen reshreshe. Og scriptet vil starte på ny.

 

- Idiotisk metode.

 

#edit: Ser du nevner cronjob. Vil sansynligvis løse saken.

Endret av warpie
Lenke til kommentar

Vel, hvis jeg hadde vært deg og vært i Linux(?) hadde jeg laget et script i et annet språk som kunne ha startet crawlingen på forskjellige tidspunkt, f.eks Python (veldig enkelt å lage script i).

 

Denne kunne ha gått i en evig while-loop som sjekker hvor lang tid som har gått.

pseudo-kode:

 

start timer

while True:
   check timer
   if timer <= 5 minutt:
        get page to crawl
        crawl page
   else:
        sleep(60)
        reset timer

 

Tror det er verre å gjøre det i PHP.

Lenke til kommentar

Hmm.. Interessant.

Beklagligvis så har jeg ingen kjenskap til python, og ut i fra den lille kunskapen jeg har, så er språket bygd opp en del anderledes en php. Noe som krever MYE tid for å lære. Jeg kan php ganske greit, og tenker fortsette her en stund til, iallefall intill jeg ser en virkelig nødvendighet i et annet språk [=

Endret av tROOP4H
Lenke til kommentar

Hmm.. Interessant.

Beklagligvis så har jeg ingen kjenskap til python, og ut i fra den lille kunskapen jeg har, så er språket bygd opp en del anderledes en php. Noe som krever MYE tid for å lære. Jeg kan php ganske greit, og tenker fortsette her en stund til, iallefall intill jeg ser en virkelig nødvendighet i et annet språk [=

 

Hmm, har du kjennskap til cronjobs da?

Lenke til kommentar
Gjest Slettet+9871234

Dette lar seg gjøre med file_get_contents, kobinert med preg_match (_all).. Ikke at jeg er noen spesialist på regex, og preg_match_all er nytt for meg.

Du kommer vel kanskje ikke utenom bruk av regular expressions. En av PHP spesialistene på dette, Michael Schrenk sier i sin bok

 

http://www.schrenk.com/nostarch/webbots/

 

på side 45.

 

I avoid regular expressions whenever possible.

 

Men han bruker det i den boken. Han bygger også et bibliotek basert på cURL http://php.net/manual/en/book.curl.php som kan lastes ned fra bokens webside. Det er ofte bedre å stå på skuldrene til noen som allerede har gjort dette og ikke finne opp hjulet på nytt. Jeg kan anbefale den boken.

 

En annen som jeg ikke har lest er:

 

http://curl.phptrack.com/

 

cURL er laget i Sverige http://curl.haxx.se/ og skreddersydd til dette. Biblioteket er tilgjengelig i de fleste (skripting)språk som brukes i dag.

 

Se høyre kolonne her: http://curl.haxx.se/libcurl/

 

Du finner ytterligere informasjon her: http://www.digitalstart.no/

 

Lykke til med prosjektet.

Endret av Slettet+9871234
Lenke til kommentar
Gjest Slettet+9871234

Merk at å lage en web crawler er gjort med noen linjer kode om du bruker cUrl. En (et) slike (slikt) nettverk (Google har vel 1000 vis som kommer fra ulike datasentre) av crawlere kan jo krabbe opp og ned web sider i uker, måneder og år om du setter opp en kron jobb eller henter informasjonen via en Windows scheduler.

 

Der er også mange ulike teknologier som for eksempel wGet

 

http://www.gnu.org/software/wget/

 

(noen mener den teknologien er bedre på bilder), men jeg har inntrykk av cURL er den teknologien som er mest i støtet, mest generell og utvikler seg fortest.

 

Det å fylle opp en database med informasjon er ikke vanskelig. Det vanskelige er å

 

  1. Indeksere denne informsjonen på en god måte, jfr. indeksen i en bok.
  2. Skille klinten fra hveten. Effektiv datamining og parsing.
  3. Presentere informasjonen du henter inn på en god måte.

 

Google er mer maskinvare enn programvare etter min mening med 100 vis av datasentre spredt over hele kloden. Se

 

Google Revealed: The IT Strategy That Makes It Work:

 

http://www.informationweek.com/news/software/infrastructure/showArticle.jhtml?articleID=192300292

 

Det var vel denne http://pagerankandbeyond.com/ teknologien som startet Google: http://web.archive.org/web/19981111183552/google.stanford.edu/

 

Se også:

 

Webmasters, forget browsers and SE's. Make your own ethical WebBots.

 

Merk også at en crawler eller spider bare skanner overflaten av nettet.

 

The Deep Web and the Surface Web. What does it mean?

 

Så skal du lage en generell og ikke en niche crawler trenger du sikkert flere datasentre spredt over nettet med Peta bytes av lagringsplass. Komprimering og effektiv parsing (bortskrelling av markup og unødig kode) kan være viktig. Kan hende er en realtids søkemotor på utvalget sider mest interessant.

 

Har du tid så kan du også lese notetet "Combating Web Spam with TrustRank" øverst oppe på:

 

http://www.skupot.com/

 

En god hub, gode klynger som kan brukes til en seed kan være viktig.

 

Nå har du vel fått nok informasjon til en doktoravhandling.

 

Der er også mulig å basere den på to dimesjoner, PageRank - stemmer (see boken ovenfor) og TrustRank (se dokumentet ovenfor). Betydningen av de to dimensjonene kan variere basert på et eller flere spam (trust) mål i ulike nisjer.

 

Send meg gjerne koden som takk for hjelpen. Jeg vil bruke den på egne nisjer og trenger ikke konkurrere med din(e) crawlere.

 

Som sagt lykke til. Dette burde være gøy.

Endret av Slettet+9871234
Lenke til kommentar

Nå skal vi leke "finn feilen"! :D

 

function START() {
for($i=1 ; $i > -1; $i++) { //$i springer evig rundt, men skal pauses hver 100.
	if(($i<=100) AND ($i%100 == 0)) { // Jeg skal egentlig sove nå, men NEIDA!!
		echo "<br /><b>I'm takin a coffebreak... And zZzZz</b><br />"; 		
		sleep(100);
	}
	echo spider($i); //Back to crawling!
}
}

 

Hvor vidt jeg skal crawle ved bruk av curl er fremdeles usikkert, da jeg får til det samme ved hjelp av andre funksjoner, men hastigheten kan helt klart bli forbedret.

 

Som du sier, så er boten en minimalistisk del av dette prosjektet. Jeg har planer for hvordan alt skal brukes. Jeg håper å kunne lage en enkel søkemotor, med personlige premisser, personer definerer selv sitt "outcome". Slik som google har sine >200 annonyme varibler for å gi et resultat basert på hva flestparten ønsker, så tenker jegpå et system som gir muligheten til å endre slike verdier til en vis grad. Du får altså ditt eget søk, ingen søk er like. Men blir nok vanskelig, eller tidskrevende.

Endret av warpie
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...