序文:この記事を書く前に、私は主にいくつかの同様のクローラーのライティングスタイルを読みました。それらのいくつかは、それらを書くためにキューを使用していますが、それはあまり直感的ではないと感じています。一部のリクエストは1つだけで、ページ分析を実行します。彼らは自動的に起きません。これはクローラーとも呼ばれますか?したがって、私は自分のアイデアに基づいて単純なクローラーについて書きました。
アルゴリズムの紹介
このプログラムは、そのアイデアで幅広いアルゴリズムを使用し、次々と移動していないリンクの取得要求を開始し、リターンされたページを正規表現で解析し、発見されていない新しいリンクを取り出し、コレクションに追加し、次のループで移動します。
特定の実装では、Map <String、Boolean>、およびキー価値のペアがリンクとトラバースを使用するかどうかを使用します。プログラムでは、2つのマップコレクションが使用されています。つまり、OldMapとNewMapです。最初のリンクはoldMapにあり、その後、OldMapのFall Falseとのリンクのリクエストが作成され、ページを解析し、<a>タグの下のリンクを削除するためにレギュラーを使用します。このリンクがオールドマップと新しいマップにない場合、これは新しいリンクであることを意味します。同時に、このリンクが取得する必要があるターゲットWebサイトのリンクである場合、このリンクをNewMapに入れて、それを解析し続けます。ページが解析されると、OldMapの現在のページのリンクの値がtrueに設定されているため、移動されています。
最後に、古いマップによって通過していないリンク全体が通過した場合、新しいマップが空でないことがわかった場合、このループで新しいリンクが生成されたことを意味します。したがって、これらの新しいリンクは古いマップに追加され、再帰的に移動し続けます。それ以外の場合は、このループに新しいリンクが生成されていないことを意味します。ループを続けると、新しいリンクを生成できなくなります。タスクが終了したため、リンクコレクションの古いマップが返されます。
2つのプログラム実装
上記の関連アイデアは非常に明確に説明されており、コードの重要な領域にコメントがあるため、ここでは説明しません。コードは次のとおりです。
パッケージアクション; java.io.bufferedReader;インポートjava.io.ioexception; Import java.io.inputStream; impot java.io.inputStreamReader; Import java.net.httpurlconnection; Import java.net.net.malformedexception; 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>(); //ストレージリンク - トラバースであるかどうか//キー値ペア文字列oldlinkhost = ""; //ホストパターンp = pattern.compile( "(https?://)?[^/// s]*"); //例:http://www.zifangky.cn matcher m = p.matcher(baseurl); if(m.find()){oldlinkhost = m.group(); } oldmap.put(baseurl、false); oldmap = crawllinks(oldlinkhost、oldmap); for(map.entry <string、boolean>マッピング:oldmap.entryset()){system.out.println( "link:" + mapping.getkey()); }} /*** WebサイトでクロールできるすべてのWebページリンクをクロールし、アイデアで幅広い優先度アルゴリズムを使用します。 GETリクエストは、完全なセットが通過するまで通過していない新しいリンクのリクエストが常に開始されます。これは、新しいリンクが見つからず、タスクが終了することを意味します * * @param oldlinkhostドメイン名:http://www.zifangsky.cn * @param oldmapコレクショントラバース * * @return Return returnすべてのクローレッドリンクコレクション * */プライベートマップ<弦楽{map <string、boolean> newmap = new linkedhashmap <string、boolean>();文字列oldlink = ""; for(map.entry <string、boolean>マッピング:oldmap.entryset()){system.out.println( "link:" + mapping.getKey() + "---------チェック:" + mapping.getValue()); //(!mapping.getValue()){oldlink = mapping.getKey(); // get requestを開始してください{url url = new url(oldlink); httpurlconnection connection =(httpurlconnection)url .openconnection(); connection.setRequestMethod( "get"); connection.setConnectTimeout(2000); connection.setreadtimeout(2000); if(connection.getResponseCode()== 200){inputstream inputstream = connection.getInputStream(); BufferedReader Reader = new BufferedReader(new inputstreamReader(inputStream、 "utf-8"));文字列line = "";パターンパターン= pattern .compile( "<a。*?href = [/" ']?((https?://)?[^//"']+)[/" ']?。 {string newlink = matcher.trim(); = oldlinkhost + "/" + newlink newlink.startswith(oldlinkhost)){// system.out.println( " + newlink); thread.sleep(1000); } catch(arturnedexception e){e.printstacktrace(); } oldmap.replace(oldlink、false、true); }} //新しいリンクがあります。(!newmap.isempty()){oldmap.putall(newmap); oldmap.putall(crawllinks(oldlinkhost、oldmap)); //マップの特性により、キー値のペアが重複していません} return oldmap; }}3つの最終テスト結果
PS:実際、再帰の使用はそれほど良くありません。ウェブサイトにもっと多くのページがある場合、プログラムが長い間実行されるとメモリ消費が非常に大きくなるからです。
読んでくれてありがとう、私はそれがあなたを助けることができることを願っています。このサイトへのご支援ありがとうございます!