Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Monitor HTML page via CSS selector for change
#!/usr/bin/env boot
;; to run:
;; - install Boot (http://boot-clj.com/). Via brew: brew install boot-clj
;; - save this gist to a file
;; - chmod +x the file
;; - run the file
;; Settings. Change however you like.
(def url "http://www.nu.nl/")
(def selector "h1.fluid")
(def timeout (* 30 1000))
(set-env! :dependencies '[[org.clojure/clojure "1.8.0"]
[org.jsoup/jsoup "1.9.2"]
[org.clojure/core.async "0.2.385"]
[clj-http "2.2.0"]])
(require '[clojure.core.async :as a :refer [<! go-loop]]
'[clojure.string :as s]
'[clj-http.client :as client])
(import '[org.jsoup Jsoup])
(defn get-content [url]
(:body (client/get url)))
(defn page-part [url selector]
(let [content (get-content url)
parsed (Jsoup/parse content)
selected (.select parsed selector)]
(-> selected
first
str)))
(defn notify!
"OSX notification"
[message]
(.exec (Runtime/getRuntime)
(into-array String
["osascript" "-e" (format "display notification \"%s\""
message)])))
(def stop-channel (a/chan))
(defn monitor! [url selector timeout]
(let [get-html! (fn []
(let [html (page-part url selector)]
(println "received html:" (.substring html 0 50))
html))
start-html (get-html!)]
(go-loop [content start-html]
(<! (a/timeout timeout)) ;; wait
(let [new-content (get-html!)]
(if (= content new-content)
(if (= :stop
(a/alt!
stop-channel ([result] :stop)
:default :continue))
(println "stopping")
(recur new-content))
(do
(notify! "content has changed, stopping")))))))
(defn stop! []
(a/put! stop-channel :stop))
;; kick off the monitor and block
(a/<!! (monitor! url selector timeout))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment