Java Network 〜HTMLからデータ取得2〜

今回は、HTMLからのデータ取得を行う処理を実装しようと思います。その2回目です。

HTMLからデータ取得

HTMLからデータを取得する、つまりインターネットにアクセスして特定のウェブページを見る(閲覧)などして自分らが必要な情報を取得する、ということをプログラムにやらせようという分けです。

前提として、プログラム(PC)は人間ほど柔軟な思考ができるわけでもなく、我々人間が指示(プログラム)した通りにしか動いてくれません。なので一工夫が必要になります。

最近では、人工知能なんてものもありますので、この分野は広く開拓できそうです。
初めから複雑なことはできないので、1つずつ段階的に実装していきます。

データ取得Lv2

前回は、データの取得、HTMLを取得するという部分を実装しました。ソースはGithubにアップしてあります。
下のようなコードを実装しました。

// ⑴ URLを指定する
String targetUrl = "https://ja.wikipedia.org/wiki/%E6%AD%A6%E5%99%A8";
// ⑵取得したHTMLをオブジェクトにするためのクラス
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = null;
try {
    builder = factory.newDocumentBuilder();
} catch (ParserConfigurationException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
}
// ⑶ 指定したURLにアクセス、HTMLの取得
try {
    URL urlCls = new URL(targetUrl);
    urlCls.openConnection();
    InputStream inp = (InputStream) urlCls.getContent();
    Document html = builder.parse(inp);
} catch(MalformedURLException e) {
    e.printStackTrace();
} catch(IOException ie) {
    ie.printStackTrace();
} catch (SAXException e) {
    e.printStackTrace();
}

ここで使用しているクラスはJDKに入っているもので「〜.jar」をダウンロードとかしなくても使用できるコードになります。

そして、あくまでもHTMLを取得するまでの処理なのでここからがHTMLの読み込み、必要なデータの取得になります。

HTMLの読み込み

早速コードを見ていきます。

    try {
        URL urlCls = new URL(targetUrl);
        // 指定のURLにアクセス(コネクションの取得)
        urlCls.openConnection();
        // HTML文書の入力ストリーム(ファイルと同じ扱いです)
        InputStream inp = (InputStream) urlCls.getContent();
        Document html = builder.parse(inp);
        // 取得したHTMLの「ulタグ」を全て取得する
        NodeList nodes = html.getElementsByTagName("ul");
        for (int i = 0; i < nodes.getLength(); i++) {
           // 子ノードを取得し再起処理を行う loopPrint(nodes.item(i).getChildNodes());
        }

    } catch(MalformedURLException e) {
        e.printStackTrace();
    } catch(IOException ie) {
        ie.printStackTrace();
    } catch (SAXException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return "";
}
/** 再起処理を行うメソッド */
private void loopPrint(NodeList list) {
    String emp = System.getProperty("separator") + "\t\t";
    for (int i = 0; i < list.getLength(); i++) {
        Node node = list.item(i);
        if (node.hasChildNodes()) {
            loopPrint(node.getChildNodes());
        } else {
            if ("#text".equals(node.getNodeName())) {
                System.out.println("NodeName: " + node.getNodeName() + " -> Value: "+ node.getNodeValue());
            }
        }
    }
}

上の実装では「再起処理」がポイントになります。
取得したHTMLはタグで階層状になっているので階層をどんどん下がって、次のタグへ。。。というような処理が必要になります。このような時にしようするのが「再起処理」です。

つまるところは、以下のような処理です。

  1. ulタグのはじめの部分を取得
  2. タグの子ノードの有無を確認
  3. 子持ちなら、同じメソッドを呼び出す、そうでないなら中身をコンソールに表示
  4. これをルートノードの子供の数だけ繰り返す

こんな実装をしています。しかし、ulタグを取得しているだけなので、ちょっと実用的ではありません。

まとめ

駄菓子菓子、読み込み中身を取得しても、必要なデータのみを読み込むのに、色々と処理を書かないといけないので、ライブラリを使用して実装し直すことにします。使用するライブラリはJsoupです。
でわでわ。。。



投稿者:

takunoji

音響、イベント会場設営業界からIT業界へ転身。現在はJava屋としてサラリーマンをやっている。自称ガテン系プログラマー(笑) Javaプログラミングを布教したい、ラスパイとJavaの相性が良いことに気が付く。 Spring framework, Struts, Seaser, Hibernate, Playframework, JavaEE6, JavaEE7などの現場経験あり。 SQL, VBA, PL/SQL, コマンドプロント, Shellなどもやります。

コメントを残す