 | |
12.11.2007, 14:29
| Nach oben
#1 | | Erfahrener Benutzer
Registriert seit: 04.03.2007 Ort: Viernheim
Beiträge: 131
| Crawler: Rekursionproblem und Linkproblem
Hallo Leute,
ich möchte rein interesseshalber meinen eigenen Suchmaschine mit Crawler in PHP entwickeln.
Habe mir ein paar Tutorials angeschaut, u.a. Fremde Webseiten auslesen und Rekursion.
Bin derzeit noch an den Grundlagen des Crawlers dran und versuche soweit es geht, alles an "meinem" Code zu verstehen.
Bisher hab ich das hier: PHP-Code: $host = "url_geaendert";
$filestring = file_get_contents($host);
$startpos = 0;
while($pos = strpos($filestring, "<a href", $startpos))
{
$string = substr($filestring, $pos, strpos($filestring, "</a>", $pos + 1) - $pos);
if(stristr($string, 'action=showfile')) {
echo $string."<br />";
}
$startpos = $pos + 1;
}
Mein Problem hier ist, dass ich jetzt das ich nur so ein Ergebnis bekommen
(Gekürzt und geändert)
<a href="index.php?a=link">Linkname<br />
<a href="index.php?a=link">Linkname<br />
<a href="index.php?a=link">Linkname<br />
So, wie bekomm ich das nun hin, dass ich vor dem index.php?a=link meinen gecrawlten url einfüge und diese Links erneut crawle.
Danke im vorraus |
| |
12.11.2007, 16:53
| Nach oben
#2 | | Lutz
Registriert seit: 14.08.2005 Ort: Nienburg / Weser
Beiträge: 684
|
Am Einfachsten ist wahrscheinlich mittels Regular Expression die Links auszulesen: PHP-Code: <?php
if (preg_match_all ('°href="([^"]+)"°is',
$stringText
$arrayMatches
) > 0
)
{
foreach ($arrayMatches AS $integerKey => $arrayMatch)
{
// Hier kannst du die Links einzeln abarbeiten
}
}
?> Um zu verstehen, wie der RegEx arbeitet, solltest du dir allerdings vorher ein wenig über RegEx' im Allgemeinen aneignen...
__________________ Paradox ist, wenn jemand für seinen Alkoholkonsum geradestehen soll |
| |
12.11.2007, 18:23
| Nach oben
#3 | | Erfahrener Benutzer
Registriert seit: 04.03.2007 Ort: Viernheim
Beiträge: 131
| Zitat:
Zitat von MrNiceGuy Am Einfachsten ist wahrscheinlich mittels Regular Expression die Links auszulesen: PHP-Code: <?php if (preg_match_all ('°href="([^"]+)"°is', $stringText $arrayMatches ) > 0 ) { foreach ($arrayMatches AS $integerKey => $arrayMatch) { // Hier kannst du die Links einzeln abarbeiten } } ?> Um zu verstehen, wie der RegEx arbeitet, solltest du dir allerdings vorher ein wenig über RegEx' im Allgemeinen aneignen... | Danke, werde mich damit auseinander setzen |
| |
12.11.2007, 19:39
| Nach oben
#4 | | Erfahrener Benutzer
Registriert seit: 04.03.2007 Ort: Viernheim
Beiträge: 131
|
Danke, musste den Code erweitern PHP-Code: <?php $host = "url"; $filestring = file_get_contents($host); $startpos = 0; while($pos = strpos($filestring, "<a href", $startpos)) { $string = substr($filestring, $pos, strpos($filestring, "</a>", $pos + 1) - $pos); if(stristr($string, 'action=showfile')) { if (preg_match_all ('°index\.php\?([^"]+)°is',$string, $arrayMatches) > 0) { foreach ($arrayMatches AS $match) { foreach($match as $result) { if(stristr($result, 'index.php')) { echo "<a href='url/$result'>".$result."</a><br />"; } } } } } $startpos = $pos + 1; } ?> Jetzt heißt es, die letzte seite noch zu crawlen  aber das kommt morgen |
| |
12.11.2007, 20:22
| Nach oben
#5 | | Christian W. Achatz
Registriert seit: 05.02.2007 Ort: München
Beiträge: 132
|
Hallo Eyüp,
wenn das allgemeingültig funktionieren soll, dann solltest du alle Vorkommen von parsen, dir daraus die Links in einen Hashtable schreiben, damit keine Rekursionen entstehen und anschließend rekursiv über die Seiten gehen (=einem Link folgen, den Quelltext holen, parsen, ...).
|
| |
13.11.2007, 18:22
| Nach oben
#6 | | Erfahrener Benutzer
Registriert seit: 04.03.2007 Ort: Viernheim
Beiträge: 131
|
dr.e danke für den tipp.
wollen wir weiter machen, wo wir stehen geblieben sind.
jetzt bekomme ich alle vollständigen links.
nächstes problem:
ich möchte bestimmte inhalte extrahieren, dass geht sicherlich mit regex.
muss u.a. sowas parsen:
<td align="center" valign="middle"><div><strong>text mit punkt und etc.</strong></div></td>
ich muss ciherlich wie folgt vorgehen PHP-Code: $host = link $file = file_get_contents($host);
$match = preg_match_all('regex_muss_schauen_wie_das_geht', $file, $matches);
print_r($matches);
freu mich auf eure antworten |
| |
13.11.2007, 20:39
| Nach oben
#7 | | Christian W. Achatz
Registriert seit: 05.02.2007 Ort: München
Beiträge: 132
| Zitat: |
ich möchte bestimmte inhalte extrahieren, dass geht sicherlich mit regex.
| Ich behaupte jetzt mal (aus Erfahrung), dass es nicht geht, denn du musst die Möglichkeit haben, generisch Tags zu Parsen und das funktioniert mit RegExps nur sehr bedingt, da diese sehr statisch sind. Sollen das nur bestimmte Fragmente sein, ok, aber ansonsten solltest du dir einen HTML-Parser bauen oder einen fertigen verwenden. Der fertige hat den Vorteil, dass du alle Elemente in einem Objektbaum abgreifen kannst und dieser etwas schneller ist, weil in C implementiert.
|
| |
14.11.2007, 00:28
| Nach oben
#8 | | Daniel Golowin
Registriert seit: 17.11.2005 Ort: Rheinland-Pfalz, Osthofen
Beiträge: 122
|
An sich ist hier ja nur die Schwierigkeit ein RegExp in kombination mit einem Auswertungsscript zu erstellen.
Die Frage ist jetzt allerdings, was möchtest du genau erreichen?
Möglich währe auch alle HTML-Elemente und irelevanten Inhalt herauszulöschen. Dann bleibt nur der Inhalt (der Text) der Seite übrig.
Denke aber der nächste Schritt wird wohl sein den Inhalt interpretieren zu können. Da währe es sinnfoll den Inhalt in ein Array oder, wie erwähnt, in Objektbaum zu bringen. Oder soll es eine einfache Suchfunktion nach vorkommenden Wörtern werden?
Damit man dir weiter helfen kann, solltest du über diesen Punkt hinaus sein (wenn du den Inhalt parsen möchtest) : Zitat: |
'regex_muss_schauen_wie_das_geht'
| |
| |
14.11.2007, 16:53
| Nach oben
#9 | | Erfahrener Benutzer
Registriert seit: 04.03.2007 Ort: Viernheim
Beiträge: 131
| Zitat:
Zitat von dr.e. Zitat: |
ich möchte bestimmte inhalte extrahieren, dass geht sicherlich mit regex.
| Ich behaupte jetzt mal (aus Erfahrung), dass es nicht geht, denn du musst die Möglichkeit haben, generisch Tags zu Parsen und das funktioniert mit RegExps nur sehr bedingt, da diese sehr statisch sind. Sollen das nur bestimmte Fragmente sein, ok, [...] | es sind statische elemente  .
|
| |
14.11.2007, 18:37
| Nach oben
#10 | | Erfahrener Benutzer
Registriert seit: 04.03.2007 Ort: Viernheim
Beiträge: 131
|
So, habs probiert PHP-Code: <?php $host = "http://www.url";
$filestring = file_get_contents($host); $startpos = 0; while($pos = strpos($filestring, "<a href", $startpos)) { $string = substr($filestring, $pos, strpos($filestring, "</a>", $pos + 1) - $pos); if(stristr($string, 'action=showfile')) { if (preg_match_all ('°index\.php\?([^"]+)°is',$string, $arrayMatches) > 0) { foreach ($arrayMatches AS $match) { foreach($match as $result) { if(stristr($result, 'index.php')) { $host = "http://www.url$result"; $file = file_get_contents($host);
$match = preg_match_all('#<td align="center" valign="middle"><div><strong>(.*)</strong></div></td></tr></table></td>#', $file, $t);
echo "Titel: ".$t[1][0]."<br />"; echo "URL: ".$host."<br />"; $match = preg_match_all('#<br />\s(.*)<img width="261" height="53" src="img/download_button.gif" alt="Download starten" border="1" />#', $file, $p); $match = preg_match_all('#<a href="(.*)" target="_blank">#', $p[1][0], $d); echo "Detail 3: ".$d[1][0]."<br /><br />"; } } } } } $startpos = $pos + 1; } ?> Naja, jetzt werden die urls ausgegeben, aber die details nicht..
|
| |
17.11.2007, 12:46
| Nach oben
#11 | | Erfahrener Benutzer
Registriert seit: 04.03.2007 Ort: Viernheim
Beiträge: 131
|
So hab mal bissl weiter gearbeitet.
Der Code ist kürzer geworden, jetzt fehlen mir einige Funktionen, was aber nicht funktioniert.
Der Code sieht jetzt so aus PHP-Code: <?php error_reporting(E_ALL);
$host = "URL/index.php?action=showall&do=1,0,1"; $filestring = file_get_contents($host); $startpos = 0;
while($pos = strpos($filestring, "<a href", $startpos)) { $string = substr($filestring, $pos, strpos($filestring, "</a>", $pos + 1) - $pos); if(stristr($string, 'action=showfile')) { if (preg_match_all ('°index\.php\?([^"]+)°is',$string, $arrayMatches) > 0) { foreach($arrayMatches[0] as $value) { echo "URL/$value<br />"; } } } $startpos = $pos + 1; } ?>
Und ich möchte diesen Teil mit rein implementieren PHP-Code: <?php error_reporting(E_ALL); $host ='URL'; $file = file_get_contents($host);
$match = preg_match_all('#<td align="center" valign="middle"><div><strong>(.*)</strong></div></td></tr></table></td>#', $file, $t); echo "Titel: ".$t[1][0]."<br />"; echo "URL: ".$host."<br />"; $match = preg_match_all('#<br />\s(.*)<img width="261" height="53" src="img/download_button.gif" alt="Download starten" border="1" />#', $file, $p); $match = preg_match_all('#<a href="(.*)" target="_blank">#', $p[1][0], $d); if(stristr($d[1][0], 'uploaded.to')) { echo "Download Typ: Uploaded.to"; } //echo "Link: ".$d[1][0];
?> Immer wenn ich das mache, geht es nicht. Habt ihr einen Rat?
|
| |
17.11.2007, 13:02
| Nach oben
#12 | | Benjamin Steininger
Registriert seit: 02.06.2005 Ort: weiher im tiefsten Odenwald
Beiträge: 1.180
|
Nur mal so ne Frage, deute ich das richtig dass du da einfach massiv viele Links von einer anderen Seite auslesen willst und als eigene Downloads mit direkten Links zu DEREN Files anbieten willst ?
Darfst du das ? Wenn ja, stellt sich die Frage warum dir dafür keine passende API gestellt wird.
Bei mir kommt der Verdacht auf, dass das ganze nicht so ganz erlaubt ist. Kannst mich aber gerne vom Gegenteil überzeugen
Geändert von robo47 (17.11.2007 um 13:07 Uhr).
|
| |
17.11.2007, 13:06
| Nach oben
#13 | | Erfahrener Benutzer
Registriert seit: 04.03.2007 Ort: Viernheim
Beiträge: 131
|
Es ist ein projektidee, mit der ich erfahrung sammeln möchte. wenn es aus einer seite wäre, würd ich ne api verlangen, ja, is aber net so.
hoffe, das reicht an erklärung  gern darfst du mir jetzt weiterhelfen |
| |
29.11.2007, 08:01
| Nach oben
#14 | | Erfahrener Benutzer
Registriert seit: 04.03.2007 Ort: Viernheim
Beiträge: 131
|
So leute, ich bin ziemlich weit gekommen, kann durch verschiedenen strukturierte paginations crawlen.
Als ergebnis bekomme ich jetzt rund 6.000 Links, die zum letzten mal gecrawlt werden, das krieg ich hin, bloss mein script crawlt jetzt nur ne jeden 6. Link.
Hängt das am max_exec time?
|
| |
29.11.2007, 09:52
| Nach oben
#15 | | Benjamin Klaile
Registriert seit: 02.12.2004 Ort: Remagen
Beiträge: 4.480
|
Wird wirklich nur jeder sechste Link angefasst oder eben die ersten 1000 Links?
Bei ersterem scheint mir dann doch etwas am Code falsch zu sein.
|
| |
29.11.2007, 18:11
| Nach oben
#16 | | Erfahrener Benutzer
Registriert seit: 04.03.2007 Ort: Viernheim
Beiträge: 131
|
das erstere, naja am ich schau nochmal drüber, wenn ichs net hinbekomme, poste ich nochmal hier her
|
| |
29.11.2007, 20:18
| Nach oben
#17 | | Erfahrener Benutzer
Registriert seit: 04.03.2007 Ort: Viernheim
Beiträge: 131
|
Habs net hinbekommen, der macht tatsichlich nur die wenigen Links und das durcheinander: PHP-Code: <?php error_reporting(E_ALL);
$host = "url"; $filestring = file_get_contents($host);
preg_match_all('°<div style="text-align:center;font-size:12px;">(.*)<\/div>°', $filestring, $string); foreach ($string[1] as $string) { $str = preg_replace('#&#', '&', $string); if (preg_match_all ('°index\.php\?([^"]+)°is',$str, $array) > 0) { foreach ($array[0] as $array) { $url = 'url'.$array; $get = file_get_contents($url); preg_match_all('°<td class="showlasttop_font_header" colspan="2">Seite:(.*)<\/td>°', $get, $string); foreach ($string[1] as $string) { $str = preg_replace('#&#', '&', $string); if (preg_match_all ('°index\.php\?([^"]+)°is',$str, $array) > 0) { foreach ($array[0] as $array) { $url = 'url'.$array; $get = file_get_contents($url); $start = 0; while($pos = strpos($get, "<a href", $start)) { $string = substr($get, $pos, strpos($get, "</a>", $pos + 1) - $pos); if(stristr($string, 'action=showfile')) { $str = preg_replace('#&#', '&', $string); if (preg_match_all ('°index\.php\?([^"]+)°is',$str, $array) > 0) { foreach ($array[0] as $array) { $url = 'url'.$array; $get = file_get_contents($url); $m = preg_match_all('#<td align="center" valign="middle"><div><strong>(.*)</strong></div></td></tr></table></td>\s#', $get, $titel); echo '<strong>Titel:</strong> '.$titel[1][0].'<br />'; echo '<strong>Link:</strong> '.$url.'<br /><br />'; } } } $start = $pos + 1; } } } } } } } ?> ich weiß, ist viel code, wird aber noch optimiert und als universale klasse realisiert.
danke im vorraus
PS: der mittlere teil geht nicht, die letzte anweisung halt..
|
| |
29.11.2007, 21:49
| Nach oben
#18 | | Benjamin Klaile
Registriert seit: 02.12.2004 Ort: Remagen
Beiträge: 4.480
| | |