clojure.data.json write/read 影响直播数据
clojure.data.json write/read affects enlive data
保存和重新加载 enlive
的 html-resource
输出的适当 json 方法是什么。
以下过程不保留数据结构(请注意,我要求 json/read-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
谢谢。
更新
为了解决 Mark Fischer 的评论,我 post 一个不同的代码解决了 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
更简单的方法是 write/read 使用 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
Enlive 期望标签名称值也是关键字,如果标签名称值是字符串(这是 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,那么您可以使用以下方法将 :tag 值转换为关键字:
(clojure.walk/postwalk #(if-let [v (and (map? %) (:tag %))]
(assoc % :tag (keyword v)) %)
craig-reloaded)
保存和重新加载 enlive
的 html-resource
输出的适当 json 方法是什么。
以下过程不保留数据结构(请注意,我要求 json/read-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
谢谢。
更新
为了解决 Mark Fischer 的评论,我 post 一个不同的代码解决了 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
更简单的方法是 write/read 使用 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
Enlive 期望标签名称值也是关键字,如果标签名称值是字符串(这是 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,那么您可以使用以下方法将 :tag 值转换为关键字:
(clojure.walk/postwalk #(if-let [v (and (map? %) (:tag %))]
(assoc % :tag (keyword v)) %)
craig-reloaded)