ページをクロールする時に必要なAタグのみ取得するXPath

10/4 追記:メールも弾くよう改良
getElementsByTagName('a')で全部取ってくるくらいなら、XPathでフィルタリングしたい!
ということで、

/html/body//a[not(contains(@href, "#")) and not(starts-with(@href, "javascript:")) and not(starts-with(@href, "mailto:")) and string-length(@href) > 0]

こんなのどうでしょう?

説明

このXPathは、4つの判定全てを満たすAタグを取得します。
"@href"は、href要素の値です。

1つ目の判定
not(contains(@href, "#"))

contains(string1, string2)の意味は、string1の中にstring2が含まれていたら真
ですので、それをnotで否定して、hrefが"#"を含んでいないAタグを取得します。


こいつらが弾く対象

<a href="#top">このページトップへ</a>
<a href="http://example.com/index.html#top">ホームページトップへ</a>
2、3つ目の判定
not(starts-with(@href, "javascript:"))

starts-with(string1, string2)の意味は、string1string2から始まっていたら真
ですので、それをnotで否定して、hrefが"javascript:"、"mailto:"から始まらないAタグを取得します。
javascriptの場合は、"javascript:"、メールアドレスの場合は、"mailto:"で始まることが保障されているので、starts-withを使いました。


こいつらが弾く対象

<a href="javascript:alert('Hellow World!')">alert</a>
<a href="mailto:TakiTake.create@gmail.com">mail</a>
4つ目の判定
string-length(@href) > 0

string-length(string1)の意味は、string1の長さを返します。
ですので、大なり0の比較を組み合わせて、hrefの長さが0より大きいAタグを取得します。


こいつらが弾く対象

<a href="">string(0)</a>
<a></a>

後は

取得したリンク先のヘッダ取得して、"text/html"なやつだけ解析すれば良いのではないかと。