Clojureでスクレイピングしてみる

Clojureの勉強会に参加するので、勉強がてら参加者のtwitterのURL一覧を取得するスクリプトを書いてみた。


([@2012/4/20 14:40] lein run のようにシェルから実行出来るように書き換えました)
まず、Leiningenでプロジェクトを作成する。

lein new hoge
cd hoge

enlive(スクレイピング用)を使いたいのでproject.cljに以下のように記述。

(defproject hoge "1.0.0-SNAPSHOT"
  :description "FIXME: write description"
  :dependencies [[org.clojure/clojure "1.3.0"]
                 [org.clojure/clojure-contrib "1.2.0"]
                 [enlive "1.0.0"]]
  :main hoge.core)

で、

lein deps

とやると依存関係の解決とか必要なファイルの取得とかをLeiningenがやってくれる(らしい)。


後はhoge/src/hoge/core.cljに本体を記述していく。

(ns hoge.core
  (:use [net.cgrand.enlive-html]))
(import 'java.net.URL)

(defn get-members
  "ATNDのイベント番号を引数に参加者のプロフィールURLのリストを返す"
  [eid]
  (map #(str "http://atnd.org" (get-in % [:attrs :href]))
       (-> (str "http://atnd.org/events/" eid) URL.
           html-resource (select [:section#members-join :a]))))

(defn get-twitter-url
  "ATNDプロフィールURLを引数にtwitterのURLを返す(無ければnil)"
  [p-url]
  (get-in (first (filter #(-> % :attrs :href (.startsWith "http://twitter.com"))
                         (-> p-url URL.
                             html-resource (select [:div#users-show-info :a]))))
          [:attrs :href]))

(defn -main
  "ATNDのイベント番号を引数に参加者のtwitterのURLを表示する"
  [event-id]
  (apply println (map get-twitter-url (get-members event-id))))

へ、並列化はまた勉強します…><


で、

lein run 27149

のように http;//atnd.org/events/を引数に実行すると

http://twitter.com/mid_f http://twitter.com/Kuchitama http://twitter.com/_yuu_k http://twitter.com/bouzuya http://twitter.com/emanon001 http://twitter.com/taki__taki__ http://twitter.com/murase_syuka http://twitter.com/d_e_k_o_p_o_n http://twitter.com/keiskS http://twitter.com/nitro_idiot http://twitter.com/nomnel http://twitter.com/ponkore http://twitter.com/toshi_a nil http://twitter.com/manjilab http://twitter.com/camomileo http://twitter.com/sawam___ http://twitter.com/memememomo http://twitter.com/rika_t http://twitter.com/farvel

と出力される。
あれ、改行されてないけど


今度は自動でtwitterのリスト作成するとこまで出来るようにしたいなぁ。