Was du eigentlich nicht so genau wissen wolltest
Genauer: So funktioniert webeye
Es ist wohl jedem einsichtig, dass sich ein Spider kein Explorer-Update bei Microsoft holt, sondern dass die "Engine" zum Zerlegen und Bewerten des Quelltextes völlig anders funktioniert. In vieler Hinsicht arbeiten alle Suchmaschinen so oder so ähnlich.
Es kann also ganz interessant sein, sich am Beispiel "webeye" - das ich natürlich in- und auswendig kenne - die Strategien und Schwierigkeiten anzusehen. Man muss übrigens kein Programmierer sein, zum Verständnis reicht es zu wissen, was Quelltext und ein <Tag> ist.
Ich bin auch kein Programmierer, sondern Graphiker.
Jeder gute Schulaufsatz beginnt mit einem kurzen historischen Abriss, so auch hier.
(geh bitte! Zur Sache!)
Vor einiger Zeit bekam ich den Auftrag, für einen internationalen Provider eine CD-Rom mit der Zugangssoftware zu gestalten und zu programmieren. Weil das natürlich etwas mager ist, sollte zusätzlich ein sehr umfangreiches "Internet-Glossar" mit auf die CD, in Macromedia Director programmiert, aber so, dass die Struktur des Webs dargestellt wird: Viele einzelne Seiten, vielfältig untereinander mit Links verknüpft. Als Ausgangsmaterial bekam ich eine endlose Word-Datei mit etwa 1200 Einträgen, als Beispiel in der Form:
Hub
Ein Hub ist eine ->Schnittstelle innerhalb eines ->Netzwerkes, das dazu dient, die Verbindung zwischen einem ->Server und mehreren ->Clients herzustellen.
Client
Blabla ->Server Blabla ->Netzwerkverbund Blabla usw.
Daraus sollten 1200 einzelne Seiten werden, die mit einer schnellen Suchfunktion und dichter Verlinkung untereinander ausgestattet sind.
Das Zerlegen der Absätze zu einzelnen Datenbank-Einträgen stellte wenig Problem dar, die allermeisten Einträge waren durch eine - optisch gut sichtbare - Leerzeile getrennt, die erste Zeile war immer der Titel, also das Keyword, alles danach ist die Erklärung. Nach kurzer Sichtkontrolle konnte ich also die Datensätze erzeugen.
Weit schwieriger gestalteten sich die Links. Ich hätte mich brav hinsetzen können und bei a beginnen, was mir dann doch etwas mühsam erschien. Stattdessen entschied ich mich für eine Lösung, die auf den ersten Blick recht simpel klingt. Ich nehme von allen Datensätzen die Titel, und wo immer eine Seite dargestellt wird, wird jedes Wort, das in dieser Liste vorhanden ist, als Link dargestellt und führt zu diesem Eintrag.
Nichts ist unangenehmer, als knapp vor dem Ziel plötzlich stecken zu bleiben: Ich erreichte auf Anhieb 90% Treffsicherheit, was aber immer noch bedeutet: jedes 10. Wort mit einem Pfeil davor führte zu keinem Eintrag, dem Falschen und umgekehrt. In diesem Satz i7t jeder 10. Bichstabe faKsch.
Also begann ich, mich mit den Feinheiten der deutschen und englischen Sprache auseinander zu setzen, bzw mit der maschinellen Verwertung derselben: Wann hat ein Wort den gleichen Stamm wie ein anderes, wann ist das Wort Bestandteil eines anderen und wann wiederum nicht. Kurz: wie bewertet ein Programm geschriebenen Sprache.
Also: Wie stelle ich die Verbindung zwischen "Netzwerkes" und "Netzwerkverbund" her?
Derartige Spielereien faszinieren mich und haben (vorläufig) letztendlich zu webeye geführt.
Gehen wir's an - wie webeye arbeitet:
1. Start:
Ich fange abschreckend gleich einmal mit dem schwierigsten Teil an.
Nach einer kurzen Überprüfung des eingegebenen URL lädt webeye genau diese Seite. Genauer: den Quelltext - Bilder oder verknüpfte Dateien (Style-Sheets, *.js) werden nicht geladen. Dazu später.
Hier gibt es bereits die erste Hürde: webeye geht davon aus, dass die Seite, die es bekommt auch die ist, die angefordert wurde. Der kleine Unterschied: Bei www.domain.de liefert der Server z.B. die Seite www.domain.de/index.html zurück. webeye erfährt aber nicht, dass die Seite "index.html" heißt. Wenn webeye also später auf den Link zu index.html stößt, wird diese Seite erneut geladen. Das ist auch richtig so, denn die ursprüngliche Startseite hätte ja auch "default.htm" sein können. Nach einem Vergleich mit bereits geladenen Seiten merkt webeye aber, dass diese Seite schon geladen wurde und verwirft sie.
2. Fehlererkennung:
Ein Problem, das unmittelbar damit zusammenhängt, hat mich etwas länger beschäftigt:
Wenn es die Seite nicht gibt, meldet der Server normalerweise einen Fehler. Das muss aber nicht zwangsläufig so sein. Viele Server sind so konfiguriert, dass kommentarlos eine andere Seite zurückgegeben wird; etwa "error.html" oder "sitemap.html". webeye geht aber davon aus, dass die angeforderte Seite geladen wurde. Wenn webeye dann noch relative Links auf dieser Seite findet, ist der Karren verfahren, weil die Hierarchie üblicherweise nicht mehr stimmt. Die Folge ist, dass webeye erneut die Fehlerseite bekommt und sich immer tiefer in Verzeichnisse arbeitet, die es gar nicht gibt. webeye erkennt zwar, dass es sich um Dubletten handelt und wertet die Seiten nicht aus, arbeitet aber natürlich trotzdem die Links der ersten Fehler-Seite ab - es könnte ja auch einfach ein "broken Link" gewesen sein.
Ein brachialer Trick brachte Linderung: Unmittelbar nach der Startseite ruft webeye eine Seite auf , die es mit Lotto-Sechser - Wahrscheinlichkeit nicht gibt. Das, was zurückkommt ist die Antwort des Server bei Fehlern und alles was so aussieht, wird in der Folge als Fehler behandelt. Genial Brachial, oder? ;-)
Das ist übrigens kein "webeye-spezifisches" Problem, praktisch alle gleichartigen Online-Tools haben damit zu kämpfen, scheinbar auch Suchmaschinen: Bei www.webeye.at gehört die Seite error.html zu den laut Logfile am meisten aufgerufenen Seiten. Bei einer Site, die gerade mal aus 80 Einzelseiten besteht, hat man aber normalerweise nicht so viele "Broken Links", wenn man einigermaßen sauber gearbeitet hat. Woher also die vielen Fehler?
Ich gestehe: Als Starthilfe hatte ich einige Zeit ein Verzeichnis mit ca 16 Brückenseiten. Google liebt meine Brückenseiten erfahrungsgemäß sehr und ich hatte auch relativ viele Hits auf diese. Später habe ich die Seiten einfach gelöscht. Aus unerfindlichen Gründen zeigen Suchmaschinen diese Seiten immer noch an - zu sehen bekommt man aber immer "error.html", da es die Brückenseiten ja nicht mehr gibt. Deshalb die vielen Zugriffe auf "error.html"
Etwas schwieriger gestaltet sich die Sache bei dynamischen Seiten, die mittels htaccess oder mod-rewrite auf andere URLs umgeleitet werden. Da das aber recht selten vorkommt - und die Webmaster (hoffentlich) wissen, was sie tun - kann ich mit den Fehlern leben. Bei gut optimierten Seiten gibt es auch hier keine Probleme.
3.) Vorbereitung
Der Quelltext ist jetzt im Speicher und es kann losgehen:
Nicht so schnell. Zuerst überprüft webeye einmal, was denn das überhaupt ist. <head> und <body> müssen vorhanden sein. Außerdem werden 2 Kennzeichen überprüft: Bytes (=Zeichen) und Anzahl der Wörter. Wenn beides mit einer der vorher geladenen Seiten übereinstimmt, ist es eine Dublette und aus.
Es gibt zwar gelegentlich Seiten, die eigentlich keine Dubletten sind und die selben Werte aufweisen, der Informationsgehalt dieser Seiten ist aber ohnehin immer gering: Bildergalerien, etwa aus Photoshop. Die Seiten unterscheiden sich nur im Bildnamen, und wenn dieser nach einem Muster wie "DSC00012" ist, dann sind sowohl Zeichenzahl wie Wortzahl gleich. Ich könnte zwar recht einfach feststellen, dass das eine Seite aus einer Galerie ist; es hat aber keinen Sinn, die Seite hat ohnehin keinen Wert für Suchmaschinen.
Die andere Variante solcher fast identischer Seiten sind ganz billig gemachte Brückenseiten. Auch diese sind wenig interessant.
Bei üblichen, individuellen Seiten ist die Wahrscheinlichkeit, dass 2 Seiten in diesen Parametern identisch sind, sehr gering und sinkt zudem bei steigendem Informationsgehalt.
3a) Ausmisten:
Bis Version 0.5 von webeye habe ich Kommentare, Style und Scripts noch gesondert analysiert. Das Problem dabei war, dass man sich sehr viel Datenmüll einfängt, den ich zwar durch immer neue Filter wieder ausgesiebt habe, was aber auch keinen wesentlichen Gewinn gebracht hat. Einige Redaktionssysteme liefern derartig viel Schrott mit - der Rekord lag bei 80k Kommentare für 200 Zeichen verwertbaren Text - dass selbst bei schärfsten Filtern noch Variablendeklarationen in die Keywordanalyse gelangten; ein unhaltbarer Zustand.
Seit Version 0.6 wird alles zwischen <!-- und --> ratzeputz gelöscht, ebenso alles Script und Style. Damit trat eine enorme Geschwindigkeitssteigerung und Verbesserung der Analysen ein. Ich gehe davon aus, dass Suchmaschinen das genauso machen - soviel zu Keywords in Kommentaren oder Styles.
Möglicherweise werde ich in einer späteren Version von webeye noch Scripts und Styles analysieren, allerdings nur, um darauf hinzuweisen, dass Suchmaschinen bestimmte Tricks sehr wohl durchschauen. (Fontgrößen < 6 px, location.replace udgl) Da muss mir aber schon sehr fad sein; webeye ist ein Tool, das Hilfe bieten soll und keine Suchmaschine, die Spam erkennen soll.
4.) Aufbereitung
Head und Body werden getrennt behandelt. Im Head werden ausschließlich bestimmte Tags gesucht und ausgewertet, alles andere wird unbeachtet verworfen. Gesucht wird: Title, Metatags, Refresh, aus. Von den Metatags werden nur Keywords und Description beachtet. Hier unterscheidet sich webeye stark von Suchmaschinen: Wer Keywords angibt, will wohl mit diesen gefunden werden; Die Aufgabe von webeye ist es, zu überprüfen ob das möglich ist. Deswegen legt webeye viel Wert auf diese Metatags.
Das ist ein Punkt, der oft missverstanden wird: Ich habe webeye das Verlangen nach Keywords nicht mitgegeben, weil ich glaube dass Suchmaschinen Keywords für so wichtig halten. Keywords sind einfach die Stelle, wo man seine Wünsche deponieren kann - darum gehts, um die Wünsche! So sehen das übrigens auch andere Spider und lesen deswegen die Keywords.
Jepp. Weiter:
Alle Keywords werden gesammelt und zusätzlich - unabhängig von wo sie stammen - in einer globalen Keywordliste abgelegt.
Metatags für Robots werden ignoriert, robots.txt ebenso, es bleibt ohnehin alles unter uns.
Im Body wird nicht nach bestimmten Tags gesucht, sondern hier werden - umgekehrt zum Head - die Tags gelöscht und der Rest beachtet.
Zuerst aber werden alle Links gesucht und in eine Liste geschrieben. Dabei geht webeye nicht der Reihe nach vor, sondern sucht - das ist einfacher und schneller - nach Typen von Links: Zuerst Framesets, dann a href, dann Bilder usw. Es gäbe Schalter ("Flags"), um das Verhalten verschiedener Spider zu simulieren, etwa ob Links aus dem Body eines Framesets oder aus Usemaps verfolgt werden (tut webeye), da sich die Fachsimpler aber hier sehr uneinig sind, habe ich alle Flags auf "on" geschaltet, es werden sogar Links aus Options verfolgt.
Alle Links und Bilder werden in separaten Listen abgelegt, im Body wird eine Referenz hinterlegt, eine Nummer, um sie später wieder zuordnen zu können.
Apropos Bilder.
webeye beachtet nur Bilder, die eine Mindestgröße haben. Die Regel ist simpel: Fläche = (Breite - 12) * (Höhe - 12), wobei gilt: <0 = 0. Das heißt also, dass ein Bild mit 12*12 für webeye 0 Fläche hat, ein Bild mit 13*13 Pixel genau 1, 13*14 = 2 usw. Die Quadratwurzel der Fläche ergibt übrigens den Wert des Bildes, des Links darauf und des Alt-Attributes. Tja - Bilder ohne Größenangaben haben immer Fläche 100, werden also recht wenig bewertet. Derartige Methoden werden wohl alle Suchmaschinen anwenden.
Zurück zum Body:
Für Nicht-Programmierer mag folgender Umstand vielleicht nicht recht klar sein:
Der Tag <h1> ist eine Konvention, die 4 Zeichen an sich machen keine Schrift groß. webeye erkennt ebenso wie der Browser und jeder Spider eine Headline1 also nicht an irgendeiner Schriftgröße oder weil sie anders aussieht, sondern einzig daran, dass ein Tag geöffnet wird "<", danach ein h1 kommt und der Tag wieder geschlossen wird.
In webeye ist die wichtigste Funktion dazu: offset(lookforstring, instring), die genau der JavaScript-Funktion indexOf entspricht. Genauso wie die "Suchen"-Funktion in Word. Der gesamte Body wird von einer Variable in die andere geschaufelt, also: was bei der einen vorne weggenommen wird, wird bei einer anderen wieder angehängt. Der Einfachheit halber sucht webeye dabei nach "<h1", einen Tag wie "<class="menü" h1> erkennt webeye also nicht, ebenso nicht "< h1>" Groß/Klein-Schreibung ist hingegen egal. Alle Tags, für die sich webeye interessiert (h1-6, a, img,...) werden durch eigene Tags (°h1, °\h1) ersetzt, bei Bildern wird nur der Pfad und der Alt-Tag sowie eine interne Referenz erfasst.
Danach geht es schnell: Es wird ratzeputz alles gelöscht, was zwischen < und > steht. Alle schönen Tabellenkunstwerke inklusive deren Attribute sind für webeye verlorene Liebesmüh', was bleibt, ist das, was irgendwo mehr oder weniger sichtbarer Text war.
Natürlich kenne ich Einwürfe wie "Aber laut W3C darf eine Headline auch so oder so notiert sein" - jou: Wer sagt, dass sich ein Spider darum kümmern muss? Es hat ohnehin niemand ein Recht darauf, in Google gelistet zu sein. Ich gehe davon aus, dass auch der GoogleBot oder Slurp sich recht wenig Sorgen um so etwas machen. Es muss schnell gehen und jede weitere Ausnahme ist ein Rechenschritt mehr. Außer mit originellem Quelltext zu glänzen, gibt es keinen Grund, oben genannte Konstruktionen zu verwenden.
Mein Tipp: Konventionelles HTML, wie es alle machen, ist die sicherste Lösung.
5. Reduzieren
webeye hält eine reduzierte Version aller Seiten im Speicher. Um Platz und Rechenzeit zu sparen, setzt webeye jetzt nocheinmal kräftig den Rotstift an:
webeye hat eine Liste häufig vorkommender Wörter im Rucksack (deutsch und englisch). Das reicht von "der die das" bis "eventuell", also auch Begriffe, die sich als Suchbegriffe nur wenig eignen. Einiger dieser Wörter werden "gestemmt", also aus "dies" wird "diese", "dieser", "diesem" usw.
Im nächsten Schritt werden kurzerhand alle Begriffe in dieser Liste aus dem Body-Text entfernt, in einem weiteren Schritt alle Satzzeichen. Bei sehr großen Seiten bricht webeye irgendwo ab und setzt erst kurz vor Ende wieder fort. webeye speichert pro Seite maximal 4000 Byte dieses reduzierten Textes, was aber meistens ausreicht.
Dieser Text wird für die spätere Auswertung abgelegt und die nächste Seite in der Warteschlange geladen.
Die Schritte 3 bis 5 dauern auf einem mittelschnellen Computer im Schnitt 3 Sekunden pro Seite, nur Seiten mit mehr als 60k Quellcode oder sehr vielen Links dauern etwas länger.
6. Indexieren
Wenn alle Seiten geladen sind, beendet webeye das Spidern und beginnt mit der eigentlichen Analyse.
Wir haben:
Ein Liste aller Links von-zu mit den beachteten Attributen, eine Liste aller relevanten Bilder, alle Keywords, die irgendwo in den Metatags eingetragen waren, Title, Description sowie diverse Parameter jeder Seite und natürlich den reduzierten Body-Text jeder Seite, inklusive den oben erwähnten °-tags.
Die Bewertung der Links funktioniert so, wie aus verschiedenen Quellen bekannt, das Ergebnis will ich nicht "PageRank" nennen, weil sich begrenzte Systeme anders verhalten und weil der Google PageRank inzwischen etwas anders berechnet wird.
Interessant vielleicht die Bewertung der Keywords. Wir haben jetzt eine Liste, in der alle Keywords stehen, die irgendwo als Metatags eingetragen waren. Es gibt aber Leute, die keine angeben; in der irrigen Meinung, dass Keywords sowieso pfui sind. Auch bei Frontpage scheint die Möglichkeit der Keywords irgendwo ganz hinten im Handbuch zu stehen. Sind also keine angeben, wird ggf. versucht, welche aus den Descriptions zu extrahieren und wenn auch das nicht reicht, aus den Titles.
Jetzt geht webeye alle Seitentexte durch und notiert die Häufigkeit jedes einzelnen Wortes über alle geladenen Seiten. In der Folge sortiert webeye die Liste alphabetisch und prüft, ob nach Anwendung einiger Grammatik-Regeln weitere Vorkommen in der Liste entstehen. Wenn ja, werden diese zusammengerechnet und die Ähnlichkeit in einer weiteren Liste notiert.
Damit ist die Basis gegeben für die Frage aller Fragen: Sind die einzelnen Seiten für Suchmaschinen optimiert und vor allem: mit welchen Begriffen.
webeye geht dazu jetzt einfach den verbliebenen Text durch, vergleicht kreuz und quer alles mit jedem und gibt dabei jedem vorkommenden Wort einen Wert. Dieser Wert hängt von etwa 30 Parametern ab, wobei die Häufigkeit und Position im Text natürlich wichtig ist. Weitere Kriterien sind, ob der Begriff im Title vorkommt, in der Description, in den lokalen Keywords, in den Gesamt-Keywords, ob Überschrift, Linktext usw.
Die Wörter werden nach Wert sortiert und ergeben den Text, der am Ende als "Begriffe" dargestellt wird.
webeye merkt sich dabei nur den Wert des 1., 4., 10, und 30 Wortes. Durch diese 4 Werte wird eine Kurve gelegt, die bei den meisten Seiten eine bestimmte Krümmung hat. Wenn diese Krümmung stark abweicht, zeigt webeye das an. Starke Abweichungen deuten in der Regel auf "minderwertige" Seiten hin; etwa einfach gestrickte Brückenseiten, Weiterleitungsseiten, Formulare, Menü-Frames u.dgl.
Konkret:
Das alles bedeutet natürlich nicht, dass Suchmaschinen das genauso machen. Ich gehe aber davon aus, dass ähnliche Strategien verwendet werden. Da hätten wir zB die alte Geschichte mit weißem Text auf weißen Grund (oder in der gleichen Farbe). Dieser Trick ist so alt wie das Web, wird immer noch gerne eingesetzt und manch einer hält sich sogar für einen Profi, weil er verschiedene Farbdefinitionen verwendet. Dabei muss ein Spider das gar nicht erkennen: Derartige Seiten haben meist eine Krümmung nahe 1 (jedes Wort kommt genau einmal vor) oder nahe 0 (sehr wenige Wörter kommen sehr oft vor). Oder von 20 untersuchten Satzzeichen kommen nur 2 vor, dafür aber mit sehr hoher Dichte. Oder die Verteilung von häufig vorkommenden Wörtern (der, die, das) ist unüblich; das fällt bei Brückenseiten häufig auf. Oder....
In der Praxis wird allen Beurteilungskriterien ein Bonus/Malus-System zugrunde liegen, und es genügt eine einfache Abwertung, um die Seite ins Nirvana zu befördern (also keine "Bestrafung" - das würde Gewissheit voraussetzen)
Wenn webeye bewerten würde - was es nicht tut, ist ja nicht sein Job - würden mir etliche kleine Parameter einfallen, die so nebenbei abfallen und die gut geeignet wären, eine Seite auf- oder abzuwerten. Die meisten Grenzen dieser Parameter sind willkürlich, aber ich gehe davon aus, dass Suchmaschinen ähnliche willkürliche Parameter verwenden und sie in Grenzen laufend verändert bzw von anderen Parametern überstimmt werden. Als simples Beispiel würde ich etwa die minimale Anzahl von Wörtern auf einer Seite verwenden. Hast du schon mal eine Seite gefunden, die nur 10 Wörter enthält? Anders gefragt, was würdest du von einem solchen Suchergebnis halten? Die Grenze könnte - willkürlich - auch bei 30 Wörtern liegen; das würde sicher niemand bedauern.