今回は、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はタグで階層状になっているので階層をどんどん下がって、次のタグへ。。。というような処理が必要になります。このような時にしようするのが「再起処理」です。
つまるところは、以下のような処理です。
- ulタグのはじめの部分を取得
- タグの子ノードの有無を確認
- 子持ちなら、同じメソッドを呼び出す、そうでないなら中身をコンソールに表示
- これをルートノードの子供の数だけ繰り返す
こんな実装をしています。しかし、ulタグを取得しているだけなので、ちょっと実用的ではありません。
まとめ
駄菓子菓子、読み込み中身を取得しても、必要なデータのみを読み込むのに、色々と処理を書かないといけないので、ライブラリを使用して実装し直すことにします。使用するライブラリはJsoupです。
でわでわ。。。