Javaに関する質問です。

URIが文字列で与えられてそのURIが指すHTMLのtitleタグの情報を取得したいです。
# 要は「はてな」の回答フォームみたいなもんです。
Xercesのorg.w3c.dom.html.HTMLDocument#getTitle()でうまくいくのかと思いましたがそもそもHTMLDocumentの取得の仕方がよくわかりませんでした。
HttpURLConnectionを使ってがりがり処理する方法もありますがいまひとつスマートではありません。
そこで、以下のいずれかをご教授ください。

1.URIの文字列からHTMLDocumentの取得の仕方
2.HTMLDocumentはステータスコード3xxに対応(自動的にリダイレクト)しているか。(1がわかれば自分で試します。)
3.HTMLDocument以外で実現する方法(3xxに対応必須)

とりたいのはtitleタグだけです。
より高速な方法がうれしいです。

回答の条件
  • URL必須
  • 1人2回まで
  • 登録:2004/09/19 17:13:54
  • 終了:--

回答(4件)

id:afternoontea No.1

afternoontea回答回数9ベストアンサー獲得回数02004/09/19 18:46:07

ポイント20pt

http://www.w3c.org/

World Wide Web Consortium

3番の方法です。w3cからw3へ301になると思います。

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

DocumentBuilder builder = factory.newDocumentBuilder();

Document document = builder.parse(”

http://www.w3c.org/

World Wide Web Consortium

”);

NodeList nodes = document.getElementsByTagName(”title”);

System.out.println(nodes.item(0).getFirstChild().getNodeValue());

id:esseesse

ありがとうございます。

が、

これって、w3cはうまくいったんですが、www.yahoo.co.jpとかwww.google.co.jpはうまくいかないんです。

# 実はサンプルURIをyahooにしていたのでうまくできなくて悩んでいたのです。。。

参考までに、出てきた例外は

www.yahoo.co.jpの場合

java.io.UTFDataFormatException: Invalid byte 1 of 1-byte UTF-8 sequence.

at org.apache.xerces.impl.io.UTF8Reader.invalidByte(Unknown Source)

at org.apache.xerces.impl.io.UTF8Reader.read(Unknown Source)

at org.apache.xerces.impl.XMLEntityScanner.load(Unknown Source)

at org.apache.xerces.impl.XMLEntityScanner.scanData(Unknown Source)

at org.apache.xerces.impl.XMLScanner.scanComment(Unknown Source)

at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanComment(Unknown Source)

at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)

at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)

at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)

at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)

at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)

at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)

at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)

at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:124)

at html.HtmlTest.main(HtmlTest.java:21)

Exception in thread ”main”

www.google.co.jpの場合

[Fatal Error] :12:3: The element type ”meta” must be terminated by the matching end-tag ”</meta>”.

org.xml.sax.SAXParseException: The element type ”meta” must be terminated by the matching end-tag ”</meta>”.

at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)

at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)

at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:124)

at html.HtmlTest.main(HtmlTest.java:21)

Exception in thread ”main”

どちらも出力したHTMLの問題のような気もしますが、できればより柔軟に対応できるようにしたいです。

# この方法って

とかの閉じなくても通っちゃうタグがあるとNGになっちゃいますよね。。。

2004/09/19 19:20:04
id:pandanaotan No.2

pandanaotan回答回数71ベストアンサー獲得回数02004/09/19 19:47:11

ポイント20pt

http://htmlparser.sourceforge.net/

HTML Parser - HTML Parser

Xercesにこだわらないのであれば、こちらのHTMLParserを使うというのも良いのではないでしょうか?多少崩れたHTMLでもParseできると思います。

id:esseesse

確かにうまくparseできたのですが、parseの出力がしょぼいですね。

parseが標準出力限定(parseメソッド内でSystem.out.printlnをしている)なので、後の処理に使えないんですよね。。。

# GPLなんで修正してもいいんですが。

似たようなツール(もう少しツールとして完成されているもの)で他のものはないでしょうか。

ちなみに、Xercesには全然こだわっていません。

2004/09/19 20:39:50
id:afternoontea No.3

afternoontea回答回数9ベストアンサー獲得回数02004/09/19 23:42:35

ポイント30pt

タグが消されるようなのでアップローダーにソースを置きました。

やっていることは、

1.HttpClientでドキュメントを持ってくる

2.1行ずつ処理して正規表現でtitleタグをさがす

このやり方ならテキスト処理なので柔軟性は確保できると思います。

ただ、なんとなく大げさなのとHttpClientが別ホストへのリダイレクト(w3cからw3など)をサポートしていないという問題が残ります。

id:esseesse

うーん、力技でもいいんですが、

<title></p> <p> タイトル</p> <p> </title>

とかなっていたりとかさまざまなパターンを考えて実装するよりは既存ツールのほうが完成されていていいかな、と思ったわけです。

# 個人で利用するとはいえ、単体テストとかもやらないといけないわけですし。

もちろん、最後の手段として力技は考えていますので、そのときは参考にさせてもらいます。

ありがとうございます。

2004/09/19 23:59:42
id:pandanaotan No.4

pandanaotan回答回数71ベストアンサー獲得回数02004/09/20 09:05:45

ポイント40pt

CyberNeko HTML ParserとXPathを使って書いてみました。

<pre>

import java.io.*;

import java.net.*;

import org.apache.xpath.XPathAPI;

import org.cyberneko.html.parsers.DOMParser;

import org.w3c.dom.*;

import org.xml.sax.InputSource;

public class GetTitle {

public static void main(String[] args) throws IOException {

URL url = new URL(args[0]);

URLConnection con = url.openConnection();

BufferedReader br = new BufferedReader(

new InputStreamReader(con.getInputStream(),”JISAutoDetect”));

String tmp;

StringBuffer html = new StringBuffer();

while ((tmp = br.readLine()) != null) {

html.append(tmp);

}

br.close();

try {

DOMParser parser = new DOMParser();

StringReader sr = new StringReader(html.toString());

parser.parse(new InputSource(sr));

Node node = parser.getDocument();

NodeList list = XPathAPI.selectNodeList(node, ”//TITLE”);

if ( list == null || list.getLength() == 0) {

System.out.println(”Pattern Not Found.”);

return;

}

for( int i=0; i<list.getLength(); i++ ) {

Node n = list.item( i );

System.out.println( n.getNodeName() );

Node child = n.getFirstChild();

String value = child.getNodeValue();

System.out.println( value );

}

} catch (Exception e) {

e.printStackTrace();

}

}

}

</pre>

id:esseesse

ありがとうございます、少し変更して解決しました。

変更内容は以下です。

・URLConnectionをHttpURLConnectionにキャスト

・HttpURLConnection#setFollowRedirects(boolean)でリダイレクトに対応

・parser.getDocument()をorg.w3c.doc.html.HTMLDocumentにキャスト

・HTMLDocument#getTitle()でタイトル取得

URL→StringBuffer→InputSourceの流れも省略できればベストなんですが、そこは妥協点なんですかね。。。

2004/09/25 12:14:00

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません