사전 준비사항

  1. app template을 사용하여 프로젝트를 생성한다.

    lein new app clj-test-01
    

  2. project.clj 파일의 dependencies 부분에 아래와 같이 필요한 모듈을 정의한다.

    (defproject clj-test-01 "0.1.0-SNAPSHOT"
      :description "FIXME: write description"
      :url "http://example.com/FIXME"
      :license {:name "Eclipse Public License"
                :url "http://www.eclipse.org/legal/epl-v10.html"}
      :dependencies [[org.clojure/clojure "1.8.0"] [clj-http "2.2.0"] [enlive "1.1.6" :exclusions [org.clojure/clojure]]]
      :main ^:skip-aot clj-test-01.core
      :target-path "target/%s"
      :profiles {:uberjar {:aot :all}})
    
    

HTML 파싱 예제

(ns clj-test-01.core
  (:gen-class) 
  (:require [net.cgrand.enlive-html :as html])
  (:require [clj-http.client :as client]))

(use 'clojure.pprint)

(defn html-data []
  ;; clj-html 모듈을 사용하여 웹페이지의 내용을 가져온다.

  (html/html-resource (java.io.StringReader.
      (:body (client/get "http://httpbin.org"))))
)

(defn -main [& args]
  
  ;; 태그로 찾기
  (pprint (html/select (html-data) [:a]))
  
  ;; id로 찾기
  (pprint (html/select (html-data) [:#AUTHOR]))
  
  ;; class로 찾기
  (pprint (html/select (html-data) [:.bash]))
  
  ;; 태그와 class를 조합해서 찾기
  (pprint (html/select (html-data) [:code.bash]))

)

반환값

html/select 함수의 결과는 아래와 같이 맵의 리스트 형태로 반환된다.

({:tag :a, :attrs {:href "http://httpbin.org"}, :content ("HTTP")}
  ... )

각각의 맵은 태그에 대한 정보를 담고 있는데, 태그의 내용물(content)이 단순 텍스트일 경우에 :content 부에 문자열의 리스트의 형태로 들어가며, 또다른 태그일 경우는 :content 부에 다시 맵의 리스트 형태로 들어간다.


태그의 내용물이 단순 텍스트일 때, 그 첫번째 문자열을 얻는 구문은 아래와 같이 된다.
(first (:content (first (html/select (html-data) [:.bash]))))

참고사이트


<테스트 환경>
- OS : Windows 7
- Leiningen 버전 : 1.0.0
,