Enliveをさわってみたのでメモ
Enliveをさわってみたのでメモ。
導入
- project.clj の :dependencies に下記を追加
[enlive "1.1.5"]
REPLから試用
user=> (use 'net.cgrand.enlive-html) nil user=> (dir net.cgrand.enlive-html) (中略) html html-content html-resource html-snippet (中略) select (以下略)
html関数
user=> (doc html)
-------------------------
net.cgrand.enlive-html/html
([& nodes-specs])
Allows to define inline fragments with a hiccup-like syntax.
nil
user=> (html [:div {:id "divHoge"} [:input {:id "textHoge" :type "text"}]])
({:tag :div, :attrs {:id "divHoge"}, :content ({:tag :input, :attrs {:type "text", :id "textHoge"}, :content ()})})
html-resource関数
user=> (doc html-resource)
-------------------------
net.cgrand.enlive-html/html-resource
([resource] [resource options])
Loads an HTML resource, returns a seq of nodes.
nil
user=> ; clojure.java.io の reader 関数を用いて HTML resource を取得して渡してみる
user=> (use 'clojure.java.io)
nil
user=> (doc reader)
-------------------------
clojure.java.io/reader
([x & opts])
Attempts to coerce its argument into an open java.io.Read
Default implementations always return a java.io.Buffered
Default implementations are provided for Reader, Buffere
InputStream, File, URI, URL, Socket, byte arrays, charac
and String.
If argument is a String, it tries to resolve it first as
as a local file name. URIs with a 'file' protocol are c
local file names.
Should be used inside with-open to ensure the Reader is
closed.
nil
user=> (reader "http://google.com")
#<BufferedReader java.io.BufferedReader@1969526c>
user=> (html-resource (reader "http://google.com"))
({:type :dtd, :data ["html" nil nil]} {:tag :html, :attrs {
(以下略)
select関数
user=> (doc select)
-------------------------
net.cgrand.enlive-html/select
([node-or-nodes selector])
Returns the seq of nodes or fragments matched by the specified selector.
nil
user=> (select
#_=> (html [:div {:id "divHoge"} [:input {:id "textHoge" :type "text"}]])
#_=> [:input])
({:tag :input, :attrs {:type "text", :id "textHoge"}, :content ()})
user=> (select
#_=> (html [:div {:id "divHoge"} [:input {:id "textHoge" :type "text"}] [:input {:id "textToge" :type "check"}]])
#_=> [:input#textToge])
({:tag :input, :attrs {:type "check", :id "textToge"}, :content ()})
user=> (select
#_=> (html [:html [:div {:id "divHoge"} [:input {:id "textHoge" :type "text"}]] [:input {:id "textToge" :type "check"}]])
#_=> [:div :input])
({:tag :input, :attrs {:type "text", :id "textHoge"}, :content ()})
user=> (select
#_=> (html [:html [:div {:id "divHoge"} [:input {:id "textHoge" :type "text"}]] [:input {:id "textToge" :type "check"}]])
#_=> #{[:div :input] [:#textToge]})
({:tag :input, :attrs {:type "text", :id "textHoge"}, :content ()} {:tag :input, :attrs {:type "check", :id "textToge"}, :content ()})
実用
強引感が半端ないが、Yahoo!ファイナンスから板気配を取得するコードを書いてみた。
(use 'net.cgrand.enlive-html)
(use 'clojure.java.io)
(defn kehai-url
[meigara-code]
(str "http://stocks.finance.yahoo.co.jp/stocks/detail/?code="
meigara-code
"."
"T"))
(defn kehai
[meigara-code]
(let [[title-row row1 row2]
(select
(html-resource (reader (kehai-url meigara-code)))
[:.main2colL :table :tr])]
{:meigara-code meigara-code
:uri-kehai
(first
(:content
(first
(select row1 [[:td (nth-of-type 1)]]))))
:uri-kehai-kabuka
(first
(:content
(first
(select row1 [[:td (nth-of-type 3)] :strong]))))
:kai-kehai
(first
(:content
(first
(select row2 [[:td (nth-of-type 5)]]))))
:kai-kehai-kabuka
(first
(:content
(first
(select row2 [[:td (nth-of-type 3)] :strong]))))}))user=> (map kehai [4689 4755])
({:meigara-code 4689, :uri-kehai "---", :uri-kehai-kabuka "---", :kai-kehai "---", :kai-kehai-kabuka "---"}
{:meigara-code 4755, :uri-kehai "---", :uri-kehai-kabuka "---", :kai-kehai "---", :kai-kehai-kabuka "---"})