如何编写这个clojure enlive程序,以便它可以解析多个网址?

时间:2013-05-05 17:13:49

标签: clojure enlive

这是一个解析一些网站的程序。第一个站点是site1。解析该特定站点的所有逻辑都位于( - > config:site1)

(ns program.core
    (require [net.cgrand.enlive-html :as html])) 

(def config 
    {:site1   
        {:site-url 
            ["http://www.site1.com/page/1"
             "http://www.site1.com/page/2"
                 "http://www.site1.com/page/3"
             "http://www.site1.com/page/4"]
        :url-encoding "iso-8859-1"
        :parsing-index
            {:date
                {:selector 
                    [[:td.PadMed (html/nth-of-type 1)] :table [:tr (html/nth-of-type 2)] 
                    [:td (html/nth-of-type 3)] [:span]]
                :trimming-fn
                    (comp first :content) ; (first) to remove extra parenthese
                }
            :title 
                {:selector
                    [[:td.PadMed (html/nth-of-type 1)] :table :tr [:td (html/nth-of-type 2)] [:a]]
                :trimming-fn
                    (comp first :content first :content)
                }
            :url 
                {:selector
                    [[:td.PadMed (html/nth-of-type 1)] :table :tr [:td (html/nth-of-type 2)] [:a]]
                :trimming-fn 
                    #(str "http://www.site.com" (:href (:attrs %)))
                }
            }
        }})
    ;=== Fetch fn ===;

    (defn fetch-encoded-url 
        ([url] (fetch-encoded-url url "utf-8"))
        ([url encoding] (-> url java.net.URL. 
                    .getContent 
                    (java.io.InputStreamReader. encoding)
                    html/html-resource)))

现在我要解析( - > config:site1:site-url)中包含的页面在这个例子中我只使用了第一个url,但是我如何设计它实际上做了一个主人{{1对于所有网址?

for

1 个答案:

答案 0 :(得分:1)

:site1作为参数传递给parse-elementelements-list

(defn parse-element [site element]
    (into [] (map (-> config site :parsing-index element :trimming-fn)
        (html/select 
          (fetch-encoded-url
            (-> config site :site-url first)
            (-> config site :url-encoding))
          (-> config site :parsing-index element :selector)))))

(def element-lists [site]
    (apply map vector
        (map (partial parse-element site) (-> config site :parsing-index keys))))

然后映射:site1 :site2 ...键。


附录回答评论中的进一步问题。

您可以将html/select包裹在map的{​​{1}}上。类似的东西:

:site-url

(我希望我能做好准备。)

然后你可能需要检查:trimming-fn,以便它处理嵌套。 (defn parse-element [site element] (let [site-urls (-> config site :site-url)] (into [] (map (-> config site :parsing-index element :trimming-fn) map #(html/select (fetch-encoded-url % (-> config site :url-encoding)) (-> config site :parsing-index element :selector))) site-urls))) 就足够了。