Vorwort: Vor dem Schreiben dieses Artikels habe ich hauptsächlich ein paar ähnliche Crawler -Schreibstile gelesen. Einige von ihnen verwenden Warteschlangen, um sie zu schreiben, was sich nicht sehr intuitiv anfühlt. Einige haben nur eine Anfrage und führen dann Seitenanalyse durch. Sie stehen überhaupt nicht automatisch auf. Dies heißt auch Crawler? Deshalb schrieb ich über einen einfachen Crawler, der auf meinen eigenen Ideen basiert.
Eine Algorithmus -Einführung
Das Programm verwendet in seiner Idee einen Algorithmus aus dem Breite, in dem die GET-Anfragen für nicht rangierte Links nacheinander initiiert und dann die zurückgegebene Seite mit regulären Ausdrücken analysiert, die neuen Links herausnimmt, die nicht entdeckt wurden, es der Sammlung fügt und in der nächsten Schleife durchquert.
Die spezifische Implementierung verwendet MAP <string, boolean> und die Schlüsselwertpaare sind der Link und ob man durchquert werden soll. Im Programm werden zwei Kartensammlungen verwendet, nämlich: OldMap und Newmap. Der anfängliche Link befindet sich in OldMap, und dann wird eine Anforderung für einen Link mit der Flagge False in OldMap gestellt, die Seite analysiert und den Link unter dem Tag <a> regelmäßig entfernen. Wenn sich dieser Link nicht in OldMap und NewMap befindet, bedeutet dies, dass dies ein neuer Link ist. Wenn dieser Link der Link der Zielwebsite ist, die wir erhalten müssen, werden wir diesen Link in Newmap einfügen und sie weiter analysieren. Wenn die Seite analysiert wird, wird der Wert des Links auf der aktuellen Seite in OldMap auf True gesetzt, was bedeutet, dass er durchquert wurde.
Wenn der gesamte Link, der nicht durch die OldMap durchquert wurde, durchquert wurde, bedeutet dies, dass die Newmap nicht leer ist, dies bedeutet, dass in dieser Schleife neue Links generiert wurden. Daher werden diese neuen Links zum OldMap hinzugefügt und werden weiterhin rekursiv durchlaufen. Andernfalls bedeutet dies, dass in dieser Schleife keine neuen Links generiert wurden. Wenn Sie weiterhin Schleifen haben, können Sie keine neuen Links mehr generieren. Da die Aufgabe vorbei ist, wird die Link -Sammlung OldMap zurückgegeben.
Zwei Programmimplementierung
Die obigen verwandten Ideen wurden sehr deutlich erklärt, und es gibt Kommentare in den Schlüsselbereichen des Code. Ich werde hier nicht darüber sprechen, der Code lautet wie folgt:
Paketaktion; importieren java.io.bufufferedReader; import Java.io.ioxception; import Java.io.inputStream; Import Java.io.inputStreamReader; Import Java.net.httpurlconnection; Import Java.net.malformedurtexception; java.util.map; import java.util.regex.matcher; import java.util.regex.pattern; public class webcrawlerdemo {public static void main (String [] args) {webcrawlerdemo webcrawlerDemo = new webcrawlerDemo (); webcrawlerdemo.myprint ("http://www.zifangsky.cn"); } public void Myprint (String BaseUrl) {map <string, boolean> oldmap = new LinkedHashMap <String, boolean> (); // Speicherlink-ob es durchquert wird // Schlüsselwertpaar String alteLinkhost = ""; // Hostmuster p = muster.comPile ("(https?: //)? [^/// s]*"); // zum Beispiel: http://www.zifangsky.cn Matcher m = p.matcher (BaseUrl); if (m.find ()) {OldLinkHost = M.Group (); } oldmap.put (BaseUrl, false); OldMap = Crawllinks (OldLinkhost, OldMap); für (map.entry <string, boolean> macking: oldmap.entryset ()) {System.out.println ("Link:" + maping.getKey ()); }} /*** Kriechen Sie alle Webseiten -Links, die auf einer Website gekrabbt werden können, und verwenden Sie den Algorithmus der Breite Priorität in der Idee. GET -Anfragen werden ständig für neue Links eingeleitet, die erst nach dem Durchqueren des gesamten Satzes durchquert wurden. This means that new links cannot be found, and the task ends * * @param oldLinkHost Domain name, such as: http://www.zifangsky.cn * @param oldMap Collection of links to be traversed* * @return Return all crawled link collections* */ private Map<String, Boolean> crawlLinks(String oldLinkHost, Map<String, Boolean> oldMap) {Map <string, boolean> newmap = new linkedHashMap <String, boolean> (); String OldLink = ""; für (map.entry <string, boolean> mapping: oldmap.entryset ()) {System.out.println ("Link:" + maping.getkey () + "--------- prüfen:" + maping.getValue ()); // Wenn es nicht durch (! Maping.getValue ()) {OldLink = maping.getKey () durchquert wurde; // Ein Get Request -Versuch initiieren {url url = new URL (OldLink); HttpurlConnection Connection = (httpurlConnection) url .OpenConnection (); Connection.SetRequestMethod ("get"); Connection.SetConnectTimeout (2000); Connection.SetReadTimeout (2000); if (Connection.getResponSCode () == 200) {inputStream inputStream = connection.getInputStream (); BufferedReader Reader = New BufferedReader (neuer InputStreamReader (InputStream, "UTF-8")); String line = ""; Muster muster = muster .compile ("<a.*? Href = [/" ']? ((Https?: //)?/? [^/"']+) [/"]? (matcher.find ()) {String newlink = matcher.group (1) .trim (); newlink; ! e.printstacktrace (); } catch (interruptedException e) {e.printstacktrace (); } oldmap.replace (OldLink, falsch, wahr); }} // Es gibt einen neuen Link, weiterhin mit der IF (! Newmap.isempty ()) {OldMap.putall (NewMap); oldmap.putall (crawllinks (OldLinkhost, OldMap)); // Aufgrund der Eigenschaften der Karte gibt es keine doppelten Schlüsselwertpaare} oldMap zurückgeben. }}Drei endgültige Testergebnisse
PS: In der Tat ist die Verwendung von Rekursion nicht sehr gut, denn wenn die Website mehr Seiten hat, ist der Speicherverbrauch sehr groß, wenn das Programm für lange Zeit ausgeführt wird.
Danke fürs Lesen, ich hoffe, es kann Ihnen helfen. Vielen Dank für Ihre Unterstützung für diese Seite!