YQLでXPath

きのうPipesでのフィード作成がそこそこうまくいったので、YQLで同じようなことはできないかと試してみると、select * from htmlでHTMLを取ってこれた。

ここまでだと、Yahoo! Pipes とあんまり変わらない感じだけど、html テーブルを使えば任意の HTML を引っ張ってこれる。しかも、条件に xpath を指定できる。
たとえば Yahoo!ニュース からヘッドラインをとってきてみよう。

select * from html
  where
    url="http://headlines.yahoo.co.jp/hl"
      and
    xpath="//li[@class='yjMt']/a"

(中略)
残念ながら valid な HTML じゃないとエラーが返ってくるので、現時点ではほとんどの URL で失敗してしまう。ちゃんと動くようになったとしたら恐ろしく楽しそうですね。

米 Yahoo! が SQL っぽく色んなデータを取ってこれるAPIを出した - てっく煮ブログ 跡地

ということなのでたまたまvalidだったのかな。他のページで試してみるとエラーになるのもあった。改善されて取れるページが多くなったのかも。
YQL式はこんな感じ。

select * from html
  where
    url="http://www.happyhardcore.com/forums/portal_news.asp"
      and
    xpath="//td[@bgcolor='#396FC1']/table[@bgcolor='#396FC1']"

これで各項目をあらわすtableはバッチリ取れた
しかし、実は元のHTMLにはtd[@bgcolor='#396FC1']の外側のtrに<a name="2564"></a>というふうに記事番号のアンカーが入っていて、Pipesではそれを使ってパーマリンクを生成したのだが、YQLで読み込むとアンカーが消えちゃってる*1。なぜ? たぶんHTMLを読み込む過程で何らかの正規化処理が入ってるんだろうなぁ。もしアンカーがあれば、XPathの最後に"/../.."をくっつけてやればOKのはず。
というわけで、記事番号が取れないのでこの場合はあんまり使えないことになってしまった。まあすべてのHTMLがちゃんと構造化してるとは限らないわけで、しょうがないけどね。

*1:空要素だから消えたのかと思ったらそうではなく、正確には全アンカーが最初のtableの前に移動している