Suchmaschine selber programmieren
In diesem Artikel zeige ich euch, wie ihr selber eine kleine Suchmaschine programmiert. Suchmaschine ist vielleicht etwas übertrieben. Tatsächlich geht es um einen Webcrawler, aber dieser liefert uns alle benötigten Daten für eine Suchmaschine. Einsatzgebiet solcher kleinen Suchmaschinen sind beispielsweise Webseiten die dadurch relativ schnell und einfach durchsucht werden können. Man kann einen Index erstellen oder im einfachsten Fall eine Sitemap aufbauen.
Suchmaschine selber programmieren
Was benötigen alle Suchmaschinen dringender als Menschen Luft zum Atmen? Richtig: Daten. Ohne diesen könnte keine kein Suchergebnis zurückgeliefert werden. Die Frage ist nur: Woher? Auch hier ist die Antwort einfach: aus dem Internet.
Suchmaschinen wie Google nutzen so genannte Webcrawler. Das sind einfache Computerprogramme die von Link zu Link im Internet herum navigieren und dabei die Daten der Webseiten (deren HTML Code) lesen und speichern. Gute Webcrawler bzw. gute Suchmaschinen speichern diese Daten natürlich in einer intelligenten Art und Weise, so dass man schnell zu einem Schlüsselwort alle wichtigen Links findet. Für unser kleines Beispiel verzichten wir mal darauf und speichern uns nur die Links einer HTML Seite.
Mein PHP Webcrawler
Für einen simplen Webcrawler brauchen wir folgende Dinge:
- eine Datenbank in der wir unsere Ergebnisse speichern
- eine Funktion, die uns zu einer URL den HTML Code liefert
- viel Zeit…
<?php $url = "http://www.developer-blog.net"; print_r(find_all_links($url)); function find_all_links($url) { $htmlData = file_get_contents($url); if(preg_match_all('/<a\s+href=["\']([^"\']+)["\']/i', $htmlData, $links, PREG_PATTERN_ORDER)) { return array_unique($links[1]); } return array(); } ?>
Dieses Codebeispiel ist bereits der Kern des Webcrawlers. Die Funktion find_all_links liefert in einem Array alle Links der übergebenen URL, oder ein leeres Array, falls keine gefunden wurden. Es werden hier 2 wichtige Funktionen verwendet:
- file_get_contents
Diese Funktion liefert den Inhalt einer Datei als String. Das tolle an dieser Funktion ist, dass man hier auch URLs übergeben kann. - preg_match_all
Mit dieser Funktion kann ein String gegenüber eines Regulären Ausdrucks (kurz Regex) getestet werden. Nähere Informationen zu Regulären Ausdrücken kann man im Internet finden. In diesem Fall definieren wir einen Ausdruck, der alle <a href> Tags des HTML Codes findet. Die Ergebnisse werden uns im 3. Parameter zurückgegeben.
Nachdem wir nun die Links bekommen haben, müssen wir sie natürlich auch irgendwo speichern. Zu diesem Zweck erstellen wir eine MySQL Datenbank und erzeugen uns eine einfache Tabelle:
CREATE TABLE `links` ( `link` varchar(255) NOT NULL, `id` int(10) unsigned NOT NULL auto_increment, PRIMARY KEY (`id`), UNIQUE KEY `link` (`link`) ) ENGINE=MyISAM CHARSET=utf8
Jetzt erweitern wir noch unseren Webcrawler um eine Datenbankanbindung. Danach werden alle Links brav in der Tabelle gespeichert.
<?php $url = "http://www.developer-blog.net"; $mysqli = new mysqli("127.0.0.1", "root", "","test"); if($mysqli->connect_error){ echo "unable to connect to Database: ".mysqli_connect_error()."\n"; exit(); } $links = find_all_links($url); links_to_db($links, $mysqli); function find_all_links($url) { $htmlData = file_get_contents($url); if(preg_match_all('/<a\s+href=["\']([^"\']+)["\']/i', $htmlData, $links, PREG_PATTERN_ORDER)) { return array_unique($links[1]); } return null; } function links_to_db($links, $mysql) { //urls to db foreach($links as $link){ $allowed = true; //check if url exists $statement = "SELECT * FROM `links` WHERE link = ?"; if($stmt = $mysql->prepare($statement)){ $stmt->bind_param("s", $link); $stmt->execute(); $stmt->store_result(); if($stmt->num_rows>0){ $allowed=false; } $stmt->close(); } //insert into DB if($allowed){ $statement = "INSERT INTO `links` (link) VALUES (?)"; if($stmt = $mysql->prepare($statement)){ $stmt->bind_param("s", $link); $stmt->execute(); $stmt->close(); } } } } ?>
Die Funktion links_to_db kümmert sich darum, dass unsere Links auch in der Datenbank landen. Außerdem wird hier noch bei jedem Link geprüft, ob er bereits in der Datenbank existiert. Das ist nicht unbedingt nötig, da in unserem Fall die Funktion find_all_links ja bereits doppelte Links verhindert.
Das wars soweit. Unser einfacher Webcrawler kann nun alle Links einer HTML Seite erkennen und speichern. Tatsächlich ist das aber erst der erste Schritt. Unser Webcrawler müsste nun alle gefundenen Links wieder wie mit dem Startlink abarbeiten, danach alle dieser Seite und so weiter. Im Idealfall startet der Webcrawler auf irgend einer beliebigen Webseite, läuft danach endlos weiter und liefert uns so lange Daten, biss unsere Datenbank voll ist!
Was fehlt zu Suchmaschine?
Wie bereits oben erwähnt genügt es nicht nur Links von Seiten zu speichern. Suchmaschinen bringen Links, Domains und Seiten in einen Kontext. Dabei ist vor allem der Text der Seite ausschlaggebend. Jedoch gibt es noch mehr. Zum Beispiel Metainformationen die der Seitenbesucher gar nicht zu sehen bekommt. Oder auch die so genannten Keywords, durch diese man erst die Seite findet. Wer mehr darüber wissen möchte, der sollte sich zum Thema SEO Optimierung einlesen. In den letzten Wochen habe ich so sehr viel dabei gelernt, warum manche Seiten eher gefunden werden als andere.
Alternativen
Wie immer gibt es im Internet zahlreiche Bibliotheken und Projekte die sich mit genau diesem Thema beschäftigen. Eine sehr gute Bibliothek heißt Caterpillar. Obwohl ich sie selber noch nie benutzt habe hat sie mir doch zumindest von der Funktionsweise beeinflusst.
Fazit
Dank PHP und einer MySQL Datenbank ist es sehr einfach einen eigenen Webcrawler zu programmieren. Diesen kann man benutzen um ihn auf die eigenen Webseiten los zu lassen oder fremde Homepages zu Indexieren. Mit der nötigen Optimierung, genügend Speicherplatz und genug Systemressourcen kann man damit auch beginnen das große Internet zu durchsuchen. Man muss sich nur bewusst sein, dass die Indexierung von 14 Milliarden Webseiten sehr viel Speicherplatz benötigt. Und der Webcrawler wird dafür sicher Jahre benötigen!
Cooles Tutorial!
hi, wie kann ich den Quellcode ausführen?
Mit PHP. D.h. auf einem Webserver. Bei den meisten Hosting Varianten ist PHP Standard. Lokal kannst du das zB mit Xampp ausführen oder auf Linux auch in der Kommandozeile z.B. mit: php index.php
Hallo, danke für das Tutorial. Wenn ich das richtig verstehe, wird hier nur die Website developer-blog.net durchgesucht richtig? Wie kann ich mehrere aber nur bestimmte Seiten durchsuchen lassen ? z.B. ich will nur 5 bestimmte große Webseiten durchsuchen und indexen mehr nicht.
Ganz einfach, du musst das Skript ändern. Erstelle einfach ein Array $url mit deinen 5 Domains und baue eine Schleife ein, die das Array durchgeht. Die Ausgabe mit print_r würde ich am besten in eine Datei mit dem Domainnamen als Dateiname schreiben. Und schon hast du 5 Sitemaps!
Hallo habe da auch mal eine frage und würde mich über eine Antwort freuen.
Ich habe ein Projekt bei dem ich einfach nicht aus dem Start rauskomme und suche einen Programmierer der sich gerne daran beteiligen will mit freiwilliger arbeit.
😉
Dabei sollte ich sagen das es nicht so schwer ist aber Google in den Schatten stellen wird.
;.)
Da bin ich mir sicher.
Klingt ja aufregend. Anfragen bitte an die im Impressum angegebene Email Adresse!
Hallo,
was mir nicht ganz klar ist: Ich würde gerne sinnvoll suchen, und nicht nur von irgendeiner URL loslegen, sprich: Ich will z.B. alle Vertreter eine Berufsgruppe in einer Stadt (oder allen Städen) Deutschlands haben.
Also so wie wenn ich Google dazu einsetzen würde, um z.B.
Rechtsanwalt Hamburg
Rechtsanwalt Hannover
Rechtsanwalt Münster
usw. aufzurufen, und dann die Ergebnisse durchsuchen. Geht so was? Wenn ja, wie?
Hallo,
Natürlich. Nur musst du in diesem Fall deine Suche auf einer bestehenden Suchmaschine aufbauen. Du kannst in deinem Programm ja Keywords wie „Rechtsanwalt Hannover“ definieren und dann diese bei zB Google suchen und auf der Ergebnisseite der zb ersten 10 Seiten alle x Links in die Tiefe gehen. Also als Startpunkt quasi
https://www.google.at/search?rlz=1C9BKJA_enAT634AT634&hl=de&ei=RFhLVuWeCeShyAP8z4yIAg&q=rechtsanwalt+hamburg&oq=rechtsanwalt+hamburg&gs_l=mobile-gws-serp.3..0l5.4083.12328.0.13200.26.26.0.14.14.0.356.5311.0j13j7j5.25.0….0…1c.1.64.mobile-gws-serp..5.21.1346.3.YWaYineSSCs
Das ist übrigens so ein Henne Ei Problem. Ohne bestehenden Index wirst du nur fündig, wenn du alles durchsuchst. Du kannst aber auch jeden bestehenden Index verwenden – dessen Qualität definiert dann das Ergebnis. Du könntest auch das Ergebnis mehrerer Suchmaschinen als Ausgangspunkt kombinierten.
bin gerade auf dieser Seite gelandet.
Ich weiß zwar nicht ob es nach so langer Zeit noch eine Antwort gibt, aber ich versuche es.
Kann ich das Suchergebnis auch in eine Variabel speichern?
Das Ergebnis von find_all_links wird schon in der Variabel $links gespeichert. Da diese ja nicht permanent ist (RAM) wird sie in die DB geschrieben. Alternativ kann man das auch in eine Datei machen. Oder verstehe ich die Frage falsch?
Hallo Werner,
danke für deine Mühe
ich habe die google-suche in die Variabel $url gesetzt, dann bekomme ich im array $links meine gesuchten Links
$url = „https://www.google.at/search?q=rechtsanwalt+hamburg&num=100“;
$links = find_all_links($url);
Gruß
Klaus
Hallo,
mir ist da was noch nicht ganz klar. Muss ich jetzt also nur den letzten Teil in mein Script einbauen, und auf meiner index.php mit dem action-befehl auf diese .php datei verweisen?
Und dann nur noch eine Tabelle mit den Daten hier „CREATE TABLE `links` (
`link` varchar(255) NOT NULL,
`id` int(10) unsigned NOT NULL auto_increment,
PRIMARY KEY (`id`),
UNIQUE KEY `link` (`link`)
) ENGINE=MyISAM CHARSET=utf8“
erstellen, oder muss ich diese Datei hier auch irgendwo im Script einbauen?
ja genau, die Tabelle erstellen und das letzte Skript anwenden.
Hallo,
wenn ich das Script auf meinen Webserver (aktuelle Version 5.2.4.) lade, mit der entsprechenden Datenbank verknüpft, wird dieses immer wieder ausgeführt (zu dem Zeitpunkt, zu dem ich es hochlade)? Oder muss man es manuell „starten“?
Kurzum: Wie funktioniert Start und Stop des Scripts?
Danke übrigens für die Mühe das online zu stellen!
es gibt zwei Möglichkeiten, wie man PHP Skripte automatisch laufen lassen kann. Die beste ist, indem man einen Cronjob durch Crontab definiert. Das sollte eigentlich jeder Hoster unterstützen. Die zweite aber viel schlechtere Variante ist das Skript bei jedem Seitenaufruf (zB index.php) einzubinden. Klappt zwar, macht aber jeden Seitenaufruf langsamer…
bekomme mit meiner kleinen Suchmachine oft die Meldung „504 Gateway Time-out nginx“.
gibt es mit PHP eine Möglichkeit, das der Browser nach einer gesetzen Zeitverzögerung weiter arbeitet.