JavaでJTidy + XPathを使ってAタグのhref属性を取得してみた。
参考文献から。
javax.xml.xpath (Java Platform SE 6)
いかにXPathを使わないとなると、DOMの解析が面倒か分かる。
未だにうちの現場では面倒な方法でDOMの解析をしていた。
あーやれやれ。
・XPathの書き方はこちら
ここも整然としていてGood。
今日ははてなブログ(当ブログ)の発リンクのリンク先を取得しました。
DOMの構築はJTidyを使った。
JTidyでパースしないと、DOM構築時にExceptionが出てしまうから。
下記のようなメソッドを作った。
HTTPレスポンスをそのまま渡せばDOMを構築してくれる。
/**
* DOM構築
* @param inputStream HTTPレスポンスをそのまま
* @return Document 構築されたDOM
*/
private Document parseDomByTidy(InputStream inputStream) {
Tidy tidy = new Tidy();
tidy.setQuiet(true);
tidy.setShowWarnings(false);
tidy.setForceOutput(false);
return tidy.parseDOM(inputStream, null);
}
構築したDOMに対して、XPathでAタグのhrefをNodeListとして取得した。
NodeListはfor文で回して、Node#getNodeValue()でリンク先を取得した。
try {
// DOM構築
Document document = this.parseDomByTidy(inputStream);
// Xpath作成
XPath xpath = XPathFactory.newInstance().newXPath();
// ノードリスト取得
NodeList nodeList = (NodeList) xpath.evaluate(
"//a/@href", document, XPathConstants.NODESET);
// 1回目:各ノード内容表示
System.out.println("aタグの数:" + nodeList.getLength());
for (int i = 0; i < nodeList.getLength(); i++) {
Node aTagNode = nodeList.item(i);
System.out.println(aTagNode.getNodeValue());
}
// ノードリスト取得
System.out.println("★<h1>タグ内の<a>タグを抽出★");
nodeList = (NodeList) xpath.evaluate(
"//h1/a/@href", document, XPathConstants.NODESET);
// 2回目:各ノード内容表示
System.out.println("aタグの数:" + nodeList.getLength());
for (int i = 0; i < nodeList.getLength(); i++) {
Node aTagNode = nodeList.item(i);
System.out.println(aTagNode.getNodeValue());
}
} finally {
inputStream.close();
}
実行結果(コンソール)は↓↓
line 119 column 9 - Error: <header> is not recognized!
line 147 column 17 - Error: <article> is not recognized!
line 149 column 5 - Error: <header> is not recognized!
line 152 column 12 - Error: <time> is not recognized!
aタグの数:97
#
http://noric0124.hatenablog.jp/
http://noric0124.hatenablog.jp/entries/2013/12/18
http://noric0124.hatenablog.jp/entry/2013/12/18/%E3%83%A4%E3%83%95%E3%83%BC%E3%82%88%E3%82%8A%E3%82%82%E7%B0%A1%E5%8D%98%E3%81%AAHTML%E3%82%92JTidy%E3%81%A7DOM%E8%A7%A3%E6%9E%90%E3%80%82
http://www.html-cool.com/samples/tryhtml_basic.html
http://www.html-cool.com/samples/tryhtml_basic.html
http://noric0124.hatenablog.jp/entry/2013/12/18/%E3%83%A4%E3%83%95%E3%83%BC%E3%82%88%E3%82%8A%E3%82%82%E7%B0%A1%E5%8D%98%E3%81%AAHTML%E3%82%92JTidy%E3%81%A7DOM%E8%A7%A3%E6%9E%90%E3%80%82
http://blog.hatena.ne.jp/guide/pro
http://noric0124.hatenablog.jp/entries/2013/12/18
http://noric0124.hatenablog.jp/entry/2013/12/18/JTidy%E3%81%AFSAX%E3%81%98%E3%82%83%E3%81%AA%E3%81%8F%E3%81%A6DOM
http://sourceforge.jp/projects/sfnet_jtidy/
http://d.hatena.ne.jp/keyword/Google%CB%DD%CC%F5
http://d.hatena.ne.jp/keyword/Java
http://d.hatena.ne.jp/keyword/Java
http://noric0124.hatenablog.jp/entry/2013/12/18/JTidy%E3%81%AFSAX%E3%81%98%E3%82%83%E3%81%AA%E3%81%8F%E3%81%A6DOM
http://noric0124.hatenablog.jp/entries/2013/12/18
http://noric0124.hatenablog.jp/entry/2013/12/18/DOM%E3%81%A8SAX%E3%81%AF%E9%81%95%E3%81%86%E3%80%82
http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EC%A5%A4%A5%D4%A5%F3%A5%B0
http://www.atmarkit.co.jp/ait/articles/0208/20/news002.html
http://d.hatena.ne.jp/keyword/XML
http://d.hatena.ne.jp/keyword/API
http://d.hatena.ne.jp/keyword/%A5%C7%A5%D5%A5%A1%A5%AF%A5%C8%A5%B9%A5%BF%A5%F3%A5%C0%A1%BC%A5%C9
http://d.hatena.ne.jp/keyword/Document%20Object%20Model
http://d.hatena.ne.jp/keyword/API
http://d.hatena.ne.jp/keyword/API
http://d.hatena.ne.jp/keyword/XML
http://d.hatena.ne.jp/keyword/API
http://d.hatena.ne.jp/keyword/XML
http://d.hatena.ne.jp/keyword/%B9%BD%CA%B8%B2%F2%C0%CF
http://d.hatena.ne.jp/keyword/XML
http://d.hatena.ne.jp/keyword/XML
http://d.hatena.ne.jp/keyword/XML
http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EC%A5%A4%A5%D4%A5%F3%A5%B0
http://d.hatena.ne.jp/keyword/XML
http://d.hatena.ne.jp/keyword/XPath
http://d.hatena.ne.jp/keyword/XQuery
http://noric0124.hatenablog.jp/entry/2013/12/18/DOM%E3%81%A8SAX%E3%81%AF%E9%81%95%E3%81%86%E3%80%82
http://noric0124.hatenablog.jp/entries/2013/12/17
http://noric0124.hatenablog.jp/entry/2013/12/17/JTidy%E3%82%92%E4%BD%BF%E3%81%88%E3%81%B0DOM%E3%81%8C%E6%A7%8B%E7%AF%89%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%89%E3%81%97%E3%81%84%E3%80%82
http://d.hatena.ne.jp/keyword/%A4%CF%A4%C6%A4%CA%A5%D6%A5%ED%A5%B0
http://d.hatena.ne.jp/keyword/XML
http://d.hatena.ne.jp/keyword/IBM
http://d.hatena.ne.jp/keyword/IBM
http://www.ibm.com/developerworks/jp/java/library/j-jtp03225/
http://d.hatena.ne.jp/keyword/XML
http://d.hatena.ne.jp/keyword/XML
http://d.hatena.ne.jp/keyword/XPath
http://sourceforge.jp/projects/sfnet_jtidy/
http://d.hatena.ne.jp/keyword/IBM
http://noric0124.hatenablog.jp/entry/2013/12/17/JTidy%E3%82%92%E4%BD%BF%E3%81%88%E3%81%B0DOM%E3%81%8C%E6%A7%8B%E7%AF%89%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%89%E3%81%97%E3%81%84%E3%80%82
http://noric0124.hatenablog.jp/entries/2013/12/15
http://noric0124.hatenablog.jp/entry/2013/12/15/%E3%83%A4%E3%83%95%E3%83%BC%E3%82%82DOM%E8%A7%A3%E6%9E%90%E3%81%97%E3%82%88%E3%81%86%E3%81%A8%E3%81%97%E3%81%9F%E3%82%89%E3%80%81SAXParseException%E3%80%82
http://d.hatena.ne.jp/keyword/%A4%CF%A4%C6%A4%CA%A5%D6%A5%ED%A5%B0
http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EC%A5%A4%A5%D4%A5%F3%A5%B0
http://noric0124.hatenablog.jp/entry/2013/12/15/%E3%83%A4%E3%83%95%E3%83%BC%E3%82%82DOM%E8%A7%A3%E6%9E%90%E3%81%97%E3%82%88%E3%81%86%E3%81%A8%E3%81%97%E3%81%9F%E3%82%89%E3%80%81SAXParseException%E3%80%82
http://noric0124.hatenablog.jp/entries/2013/12/15
http://noric0124.hatenablog.jp/entry/2013/12/15/%E3%81%AF%E3%81%A6%E3%81%AA%E3%83%96%E3%83%AD%E3%82%B0%E3%82%92DOM%E8%A7%A3%E6%9E%90%E3%81%97%E3%82%88%E3%81%86%E3%81%A8%E3%81%97%E3%81%9F%E3%82%89%E3%80%81SAXParseException%E3%80%82
http://d.hatena.ne.jp/keyword/%A4%CF%A4%C6%A4%CA%A5%D6%A5%ED%A5%B0
http://d.hatena.ne.jp/keyword/XML
http://d.hatena.ne.jp/keyword/IBM
http://www.ibm.com/developerworks/jp/xml/library/x-saxerror.html
http://d.hatena.ne.jp/keyword/%A4%CF%A4%C6%A4%CA%A5%D6%A5%ED%A5%B0
http://d.hatena.ne.jp/keyword/XML
http://noric0124.hatenablog.jp/entry/2013/12/15/%E3%81%AF%E3%81%A6%E3%81%AA%E3%83%96%E3%83%AD%E3%82%B0%E3%82%92DOM%E8%A7%A3%E6%9E%90%E3%81%97%E3%82%88%E3%81%86%E3%81%A8%E3%81%97%E3%81%9F%E3%82%89%E3%80%81SAXParseException%E3%80%82
http://noric0124.hatenablog.jp/entries/2013/12/13
http://noric0124.hatenablog.jp/entry/2013/12/13/XML%E8%A7%A3%E6%9E%90%E3%81%A7%E3%81%AF%E3%80%81%E7%B5%B6%E5%AF%BE%E3%81%ABXPath%E3%82%92%E4%BD%BF%E3%81%84%E3%81%9F%E3%81%84%E3%80%82
http://d.hatena.ne.jp/keyword/XPath
http://d.hatena.ne.jp/keyword/W3C
http://d.hatena.ne.jp/keyword/XML
http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EC%A5%A4%A5%D4%A5%F3%A5%B0
http://d.hatena.ne.jp/keyword/XPath
http://d.hatena.ne.jp/keyword/XML
http://d.hatena.ne.jp/keyword/XPath
http://d.hatena.ne.jp/keyword/XPath
http://d.hatena.ne.jp/keyword/XPath
http://d.hatena.ne.jp/keyword/XML
http://d.hatena.ne.jp/keyword/XPath
http://ja.wikipedia.org/wiki/XML_Path_Language
http://www.techscore.com/tech/XML/XPath/XPath1/xpath01.html/
http://noric0124.hatenablog.jp/entry/2013/12/13/XML%E8%A7%A3%E6%9E%90%E3%81%A7%E3%81%AF%E3%80%81%E7%B5%B6%E5%AF%BE%E3%81%ABXPath%E3%82%92%E4%BD%BF%E3%81%84%E3%81%9F%E3%81%84%E3%80%82
http://noric0124.hatenablog.jp/?page=1386946668
http://noric0124.hatenablog.jp/about
http://noric0124.hatenablog.jp/about
#
http://hatenablog.com/
http://blog.hatena.ne.jp/register?via=200109
http://staff.hatenablog.com/
http://noric0124.hatenablog.jp/archive
http://noric0124.hatenablog.jp/entry/2013/12/18/%E3%83%A4%E3%83%95%E3%83%BC%E3%82%88%E3%82%8A%E3%82%82%E7%B0%A1%E5%8D%98%E3%81%AAHTML%E3%82%92JTidy%E3%81%A7DOM%E8%A7%A3%E6%9E%90%E3%80%82
http://noric0124.hatenablog.jp/entry/2013/12/18/JTidy%E3%81%AFSAX%E3%81%98%E3%82%83%E3%81%AA%E3%81%8F%E3%81%A6DOM
http://noric0124.hatenablog.jp/entry/2013/12/18/DOM%E3%81%A8SAX%E3%81%AF%E9%81%95%E3%81%86%E3%80%82
http://noric0124.hatenablog.jp/entry/2013/12/17/JTidy%E3%82%92%E4%BD%BF%E3%81%88%E3%81%B0DOM%E3%81%8C%E6%A7%8B%E7%AF%89%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%89%E3%81%97%E3%81%84%E3%80%82
http://noric0124.hatenablog.jp/entry/2013/12/15/%E3%83%A4%E3%83%95%E3%83%BC%E3%82%82DOM%E8%A7%A3%E6%9E%90%E3%81%97%E3%82%88%E3%81%86%E3%81%A8%E3%81%97%E3%81%9F%E3%82%89%E3%80%81SAXParseException%E3%80%82
http://noric0124.hatenablog.jp/archive
http://noric0124.hatenablog.jp/about
http://hatenablog.com/
http://d.hatena.ne.jp/
★
<h1>タグ内の<a>タグを抽出★
aタグの数:8
http://noric0124.hatenablog.jp/
http://noric0124.hatenablog.jp/entry/2013/12/18/%E3%83%A4%E3%83%95%E3%83%BC%E3%82%88%E3%82%8A%E3%82%82%E7%B0%A1%E5%8D%98%E3%81%AAHTML%E3%82%92JTidy%E3%81%A7DOM%E8%A7%A3%E6%9E%90%E3%80%82
http://noric0124.hatenablog.jp/entry/2013/12/18/JTidy%E3%81%AFSAX%E3%81%98%E3%82%83%E3%81%AA%E3%81%8F%E3%81%A6DOM
http://noric0124.hatenablog.jp/entry/2013/12/18/DOM%E3%81%A8SAX%E3%81%AF%E9%81%95%E3%81%86%E3%80%82
http://noric0124.hatenablog.jp/entry/2013/12/17/JTidy%E3%82%92%E4%BD%BF%E3%81%88%E3%81%B0DOM%E3%81%8C%E6%A7%8B%E7%AF%89%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%89%E3%81%97%E3%81%84%E3%80%82
http://noric0124.hatenablog.jp/entry/2013/12/15/%E3%83%A4%E3%83%95%E3%83%BC%E3%82%82DOM%E8%A7%A3%E6%9E%90%E3%81%97%E3%82%88%E3%81%86%E3%81%A8%E3%81%97%E3%81%9F%E3%82%89%E3%80%81SAXParseException%E3%80%82
http://noric0124.hatenablog.jp/entry/2013/12/15/%E3%81%AF%E3%81%A6%E3%81%AA%E3%83%96%E3%83%AD%E3%82%B0%E3%82%92DOM%E8%A7%A3%E6%9E%90%E3%81%97%E3%82%88%E3%81%86%E3%81%A8%E3%81%97%E3%81%9F%E3%82%89%E3%80%81SAXParseException%E3%80%82
http://noric0124.hatenablog.jp/entry/2013/12/13/XML%E8%A7%A3%E6%9E%90%E3%81%A7%E3%81%AF%E3%80%81%E7%B5%B6%E5%AF%BE%E3%81%ABXPath%E3%82%92%E4%BD%BF%E3%81%84%E3%81%9F%E3%81%84%E3%80%82
正常終了です。
終了時刻:Thu Dec 19 00:44:34 JST 2013
という結果だった。
1回目はとにかくすべてのaタグのリンク先を抜き出した。
すると97件出てきた。多すぎる。
2回目ではh1タグ内にあるaタグに絞って抜き出した。
すると8件。
これは各記事タイトルに相当している。
特に意味のあるデータではないが、
XPathの練習としてやってみたました。
XPathはNodeListの取得が簡単にできるので、
表記法に慣れれば相当便利です。
ただし、最終的にはfor文で回さないといけないのが、
どうもまだ面倒な気がしますね。
もっと楽になるという記事を読みました。
後々そちらにも挑戦していこうかな。