โจทย์ก็คือไป crawl ดึงข้อมูล จาก medicare.gov
ความยากอยู่ตรง site นั้นใช้ .net เขียนแบบ component based (stateful)
การจะได้ข้อมูลมา ต้องฝ่าด่านตอบคำถาม จำนวน 4-5 หน้าเข้าไปก่อน
ก็เลยต้องใช้ browser จริงๆเข้าไปดึงข้อมูล
หวยก็เลยออกมาที่ Selenium + WebDriver
แต่ครั้นจะเขียนด้วย java ก็ไม่สนุก
เขียนด้วย ruby/python ก็เคยเขียนแล้ว
ก็เลยเลือกใช้ Clojure
Lisp มันมีข้อดีอย่างหนึ่งก็คือ
มันมี REPL ทำให้เราสามารถเขียนโปรแกรมในลักษณะ incremental ได้
เขียนไป ทดลองไป ปรับแต่งไป
สภาพแวดล้อมที่เลือกใช้พัฒนาก็คือ
emacs + cake
ลองดูตัวอย่าง ตอนทดสอบได้ใน video นี้
(ดูช่วงต้นๆก็พอ, net/web มันช้า หลังๆหมดไปกับการรอมันโหลด
ใครว่า web ราชการไทยช้า web ราชการฝรั่งก็ช้าเหมือนกัน)
Updated: video upload ผ่านทาง blogger ได้ความละเอียดต่ำเหลือเกิน
ดูรูปประกอบแล้วกัน
ตัวอย่าง code ที่ใช้
(defn send-key [by txt]
(let [elm (.findElement *driver* by)]
(.sendKeys elm (into-array [txt]))))
(defn click [by]
(let [elm (.findElement *driver* by)]
(.click elm)))
(defn init-queue []
(def *queue* (LinkedBlockingQueue.)))
(defn start-thread [driver func]
(.start
(Thread.
(fn []
(loop []
(let [code (.take *queue*)]
(binding [*driver* driver]
(func code)))
(recur))))))
(defn fetch [code]
(go "https://www.medicare.gov/find-a-plan/questions/home.aspx")
(send-key (by-css-selector "div#zip-code-field > input") code)
(click (by-css-selector "input[type=submit][alternatetext=\"Find Plans\"]")))