2015-01-23 3 views
0

enlivehtml-resource 출력을 저장하고 다시로드하는 데 적합한 json 방법은 무엇입니까? clojure.data.json 쓰기/읽기가 큰 데이터에 영향을 미침

다음은 데이터 구조 (I 심볼에 키를 매핑 JSON/읽기 str을 물어 주) 보존하지 않습니다 절차에 따라 :

(require net.cgrand.enlive-html :as html) 
(require clojure.data.json :as json) 


(def craig-home 
    (html/html-resource (java.net.URL. "http://www.craigslist.org/about/sites"))) 
(spit "./data/test_json_flow.json" (json/write-str craig-home)) 

(def craig-reloaded 
    (json/read-str (slurp "./data/test_json_flow.json") :key-fn keyword)) 

(defn count-nodes [page] (count (html/select page [:div.box :h4]))) 
(println (count-nodes craig-home)) ;; => 140 
(println (count-nodes craig-reloaded)) ;; => 0 

감사합니다.

UPDATE

작성하는 것 html/select 대신 html/html-resource

(def craig-home 
    (html/html-resource (java.net.URL. "http://www.craigslist.org/about/sites"))) 
(def craig-boxes (html/select craig-home [:div.box])) 
(count (html/select craig-boxes [:h4])) ;; => 140 

(spit "./data/test_json_flow.json" (json/write-str craig-boxes)) 
(def craig-boxes-reloaded 
    (json/read-str (slurp "./data/test_json_flow.json") :key-fn keyword)) 
(count (html/select craig-boxes-reloaded [:h4])) ;; => 0 
+1

이 잘하지 않는 것, 당신은 크레이그-다시로드와 크레이그 - 집으로 돌아된다 다른 유형, 다시로드 된 버전은 html을 반환하지 않습니다 count-nodes 방법을 사용할 수 있습니까? –

+0

@mark 당신이 옳습니다. 나는 나의 예증을 망 쳤다. 사실 제 질문은'html/select' 결과를 jsonizing하고 더 파싱하는 것이 었습니다. 나는 예제를 업데이 트 – user3639782

답변

1

보다 간단한 방법으로 해결 나는 다른 코드를 게시 마크 피셔의 코멘트를 해결하기 위해/Clojure의 edn 사용하여 읽을 :

(require '[net.cgrand.enlive-html :as html]) 
(require '[clojure.data.json :as json]) 

(def craig-home (html/html-resource (java.net.URL. "http://www.craigslist.org/about/sites"))) 

(spit "./data/test_json_flow.json" (pr-str craig-home)) 

(def craig-reloaded 
    (clojure.edn/read-string (slurp "./data/test_json_flow.json"))) 

(defn count-nodes [page] (count (html/select page [:div.box :h4]))) 
(println (count-nodes craig-home)) ;=>140 
(println (count-nodes craig-reloaded)) ;=>140 

확대 태그 이름 값이 필요합니다. 또한 키워드이기 때문에 태그 이름 값이 문자열 인 경우 노드를 찾지 않습니다 (json/write-str 및 json/read-str이 키워드를 변환하는 문자열).

(json/write-str '({:tag :h4, :attrs nil, :content ("Illinois")})) 
;=> "[{\"tag\":\"h4,\",\"attrs\":null,\"content\":[\"Illinois\"]}]" 

(json/read-str (json/write-str '({:tag :h4, :attrs nil, :content ("Illinois")})) :key-fn keyword) 
;=> [{:tag "h4", :attrs nil, :content ["Illinois"]}] 

(pr-str '({:tag :h4 :attrs nil :content ("Illinois")})) 
;=> "({:tag :h4, :attrs nil, :content (\"Illinois\")})" 

(clojure.edn/read-string (pr-str '({:tag :h4, :attrs nil, :content ("Illinois")}))) 
;=> ({:tag :h4, :attrs nil, :content ("Illinois")}) 

당신은 당신이 변환를 사용할 수 있습니다 JSON을 사용해야하는 경우 : 키워드에 태그 값을 :

(clojure.walk/postwalk #(if-let [v (and (map? %) (:tag %))] 
          (assoc % :tag (keyword v)) %) 
         craig-reloaded) 
+0

edn 제안 주셔서 감사. 그것은 clojure 단어에서 내 문제를 해결합니다. 이제 결과를 내보내고 파이썬에서 더 파싱하고 싶다고 가정 해 봅시다. '범용'형식으로 생산하고 수출하는 방법이 있습니까? – user3639782

+0

나는 내 대답을 업데이트하여 json을 읽는 방법을 포함하면서 Enlide를 통과하기 전에 태그 값을 키워드로 변환했습니다. – Symfrog

관련 문제