1

这是我html/text直接在选择器向量中使用的示例。

(:use [net.cgrand.enlive-html :as html])

(defn fetch-url [url]
  (html/html-resource (java.net.URL. url)))

(defn parse-test []
  (html/select 
   (fetch-url "https://news.ycombinator.com/") 
   [:td.title :a html/text]))

调用(parse-test)返回一个包含 Hacker News Headlines 的数据结构:

("In emergency cases a passenger was selected and thrown out of the plane. [2004]" 
 "“Nobody expects privacy online”: Wrong." 
 "The SCUMM Diary: Stories behind one of the greatest game engines ever made" ...)

凉爽的!

是否可以使用自定义函数结束选择器向量,该函数将返回文章 URL 列表。

就像是:[:td.title :a #(str "https://news.ycombinator.com/" (:href (:attrs %)))]

编辑:

这是实现这一目标的一种方法。我们可以编写自己的选择函数:

(defn select+ [coll selector+]
   (map
     (peek selector+)
     (html/select 
       (fetch-url "https://news.ycombinator.com/") 
       (pop selector+))))

(def href
  (fn [node] (:href (:attrs node))))

(defn parse-test []
  (select+ 
   (fetch-url "https://news.ycombinator.com/") 
   [:td.title :a href]))

(parse-test)
4

1 回答 1

2

正如您在评论中所建议的那样,我认为将节点的选择和转换分开是最清楚的。

Enlive 本身提供了选择器转换器。选择器来查找节点,以及转换器来,嗯,转换它们。如果您的预期输出是 html,您可能会使用选择器和转换器的组合来实现您想要的结果。

但是,看到您只是在寻找数据(可能是一系列地图?) - 您可以跳过转换位,而只需使用序列理解,如下所示:

(defn parse-test []
  (for [s (html/select 
            (fetch-url "https://news.ycombinator.com/") 
              [:td.title :a])]
    {:title (first (:content s))
     :link  (:href (:attrs s))}))

(take 2 (parse-test))
;; => ({:title " \tStartup - Bill Watterson, a cartoonist's advice ",
        :link "http://www.zenpencils.com/comic/128-bill-watterson-a-cartoonists-advice"} 
       {:title "Drug Agents Use Vast Phone Trove Eclipsing N.S.A.’s",
        :link "http://www.nytimes.com/2013/09/02/us/drug-agents-use-vast-phone-trove-eclipsing-nsas.html?hp&_r=0&pagewanted=all"})
于 2013-09-02T11:38:11.207 回答