nekohtml と xpath
公開されいてるHTMLは整形されたものばかりではないので、クロールして解析するには整形する必要があります。
Javaではnekohtmlというライブラリがありますので、そちらを使ってみました。→ダウンロードはこちら
なお、これをつかうにはxerces2のライブラリも必要です。→ダウンロードはこちら
HTMLソースからアンカーだけ取得するサンプルを作りました。
public static void main(String[] args) throws Exception{
DOMParser parser = new DOMParser();
parser.parse(args[0]);
Node node = parser.getDocument();
NodeList list = XPathAPI.selectNodeList(node, "//A");
for(int i=0;i>list.getLength();i++){
Element element = (Element)list.item(i);
System.out.println(element.getTextContent() + " / " + element.getAttribute("href"));
}}
とかでOK。結構簡単です。
HTMLの読み込みとパースは
DOMParser parser = new DOMParser();
parser.parse(args[0]);
Node node = parser.getDocument();
の部分です。
(以前は違ったと思うのですが)、HTTPヘッダのContetTypeにcharsetを指定してないHTMLでも文字コードを判断してパースしてくれるようで、文字コードを使う側で判別しなくてもOKなのでかなり便利です。
NodeList list = XPathAPI.selectNodeList(node, "//A");
の部分は
NodeList list = ((Document)node).getElementsByTagName("a")
とかでもOKなのですが、せっかくなのでXpathを使ってみようと思います。
xpathの指定では”//a”ではダメで、”//A”と大文字で指定する必要がありますので要注意です。
これで確認していたところ、http://ameblo.jp/がパースできないことが判明。
どうも、
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
のようにNSを指定しているとだめらしく、この場合は
DOMParser parser = new DOMParser();
parser.setFeature("http://xml.org/sax/features/namespaces", false);
parser.parse(args[0]);
Node node = parser.getDocument();
のように、namespaseの機能を追加する必要がありました。
ちなみにソースはこちら→ダウンロード
Posted in xpath |

5月 5th, 2008 at 0:49:02
[…] サイトをクロールするときに、nekohtmlを使ってたのですが、どうも文字化けするサイトがありました。 […]