スクレイピング
Clojureでスクレイピングといえば既にEnlive
があるのだけれど
jQueryライクな表記はClojureのシンボルでは限界あるので
ひとまずJavaのライブラリであるところのJsoup
をラップしてみた
使ってみる
1 . 準備
user> (use 'cljsoup.core)
nil
2 . URLから取ってきたHTMLをparseする
user> (def x (parse (url "https://github.com")))
#'user/x
user> x
#<Document <!DOCTYPE html> ... >
3 . Javaのクラスのままでは扱いにくいのでマッピングする
user> (nodes x)
({:type :dtd, :data ["html" "" ""]} "\n" {:tag :html, ...})
4 . CSSセレクタを使う
user> (select x "input[type=text][name=q]")
(#<Element <input type="text" data-hotkey="/ s" name="q" ...>)
user> (nodes (select x "input[type=text][name=q]"))
({:tag :input, :attrs {:type "text", :data-hotkey "/ s", :name "q", ...})
5 . 手続き的に属性(今回はname)を取ってくる
user> (-> x (select "input[type=text]") (attr "name"))
("q" "user[login]" "user[email]")
6 . HTMLを編集する(要素の直後に<div>test</div>を挿入)
user> (transform x "input[type=text]" (append (html [:div "test"])))
#<Document <!DOCTYPE html> ... >
7 . Javaのクラスから文字列に戻す
user> (parse x)
"<!DOCTYPE html> \n<html> \n <head ... "
まとめ
前回書いたdefstrictマクロを盛りまくってディスパッチしまくり
徐々にこれを拡張していってテンプレートエンジンまで持っていきたい