UrlCollector | サンプルソース | |
---|---|---|
Webページに含まれるハイパーリンクを抜き出すぞ。Javaならネットワーク経由のファイル読み込みも楽チンだ。正規表現も身につけて、文字列処理能力を高めよう! |
UrlCollector.java |
/** * 愛のJava256本ノック for Java 5.0 * Javaサンプルソース ver0.2C "UrlCollector" * UrlCollector.java 「正規表現を使ってWebサイトからリンクを抽出」 * * 2005/09/23 制作:安永ノリカズ * * 【コンパイル&実行方法】 * >javac UrlCollector.java * >java UrlCollector * 【キーワード】 * URL(Uniform Resource Locator), 検索ロボット(search robot), * 正規表現(regular expression), java.util.regex.Patternクラス, * 【試してみよう】 * 収集したURLをもとに、さらにURLを収集する。 * Webページに含まれる画像のリンクを収集する。 */ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.lang.String; import java.lang.System; import java.net.URL; import java.util.regex.Matcher; import java.util.regex.Pattern; public class UrlCollector { static final String C00 = "http://www.groovy-number.com/link.html"; static final String C01 = "<a href=\"([^\"]+)\">"; public static void main(String[] A00) { System.out.printf("[%s]から、URLを検索...%n", C00); int L00 = 0; try { URL L01 = new URL(C00); BufferedReader L02 = new BufferedReader(new InputStreamReader( L01.openStream())); String L03; Pattern L04 = Pattern.compile(C01, Pattern.CASE_INSENSITIVE); while ((L03 = L02.readLine()) != null) { Matcher L05 = L04.matcher(L03); while (L05.find()) { L00++; System.out.println(L05.group(1)); } } L02.close(); } catch (IOException L06) { System.out.println("ページ読み込み中にエラーが起きました。"); } System.out.println(L00 + "件のURLを発見しました。"); } } /* ■ クラスの外でちょっと一言 ■ Googleに代表される「ロボット型検索エンジン」というのがあります。これは検 索ロボット(クローラー、スパイダーとも呼ばれる)が、全世界のWebサイトを 自動的に巡回して、Webページをデータベースに保存していく仕組みになってま す。 その巡回の基本になってるのが、このサンプルのように、あるページに含まれる リンクを抜き出し、それを次々にたどることで、ページを収集する手法です。ち なみに、2005年3月現在、Googleは16億以上のURLを集めているとのこと。すご いっすね。 リンクを抜き出す正規表現は、"<a href=\"([^\"]+)\">"となってます。これ は、<a href="〜">という文字列のパターンを意味します。「〜」の部分には 「[^\"]+」という表現で、「ダブルクオーテーション(")以外(^)の文字が1文字 以上(+)」という指定をしています。「()」は文字のグループ化を表し、パター ンにマッチした場合、抜き出したい部分を囲んでいます。 そのパターンをコンパイルするときに指定した「CASE_INSENSITIVE」は、大文字 小文字を区別しないという意味。つまり<A HREF="〜">というタグもOKというこ とです。 Matcherのfindメソッドは、先頭からパターンにマッチする部分をサーチしま す。さらに前回発見した位置を保持してますので、再度findメソッドを呼び出し たら、その位置から後ろを探してくれます。whileループと組み合わせれば、一 行に複数のリンクが存在する場合に対応できますね。 実はこの正規表現、かなり手抜きです。URLを"で囲ってないのはダメ、シングル クオーテーション(')で囲ってもダメ、href以外の属性があるのもダメ、aの後ろ にスペースが2つ以上あってもダメ……となってます。ぜひ、より許容範囲の広 い正規表現のパターンを調べてみてください。 */