2013-05-05 55 views
0

這是解析一些網站的程序。第一個網站是site1。所有的邏輯來解析perticular站點位於( - >配置:站點1)如何編寫這個clojure enlive程序,以便它可以解析多個url?

(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))) 

現在我想分析包含在頁面( - >配置:現場1:站點URL)在這個例子中,我使用只有第一個網址,但我怎麼能設計這個實際上爲所有的網址做一個大師for

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

(def element-lists 
    (apply map vector 
     (map parse-element (-> config :site1 :parsing-index keys)))) 

(def tagged-lists 
    (into [] (for [element-list element-lists] 
      (zipmap [:date :title :url] element-list)))) 

;==== Fn call ==== 
    (println tagged-lists) 
+1

4小時前你剛剛問同樣的問題嗎? – nansen 2013-05-05 20:44:48

+0

對不起。剛剛刪除了先前的問題,謝謝! – leontalbot 2013-05-05 21:55:55

回答

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 ...鍵。


附錄在回答的意見進一步的問題。

您可以通過:site-urlhtml/select包裝在map中。喜歡的東西:

(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))) 

(我希望我得到了括號右)

,那麼你可能需要檢查:修剪-FN,爲了它來處理嵌套。一個apply應該就足夠了。

+0

太棒了!我怎麼能做到這一點,爲一個給定的網站內的多個網址? :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「] – leontalbot 2013-05-07 01:52:09

+0

您將需要重寫'parse-element'來映射」:site-url「向量,而不是將它的第一個元素包裝整個'html/select'。看我的編輯。 – 2013-05-07 02:13:17

+0

@ user1184248考慮如果答案符合您的期望,則可以進行upvoting和/或接受答案。 – 2013-05-07 02:25:03

相關問題