Clojure:读取CSV文件并将列值传递给curl

时间:2016-05-05 13:42:45

标签: curl clojure

新的clojure用户在这里。 。 。变得有点纠结。

项目目标:

  • 从csv文件中读取数据
  • 隔离第4栏中的值
  • 将值传递给html参数
  • 在curl call中使用动态创建的URL

我陷入了两个特定领域:

1)如果我在进程文件中取出println,我开始收到错误,不知道如何处理'%'(无法解析符号:在此上下文中为%)

2)在call-curl中我似乎无法将传入的id值放入URL的id参数中。

(defn call-curl [id]
  (let [url "-d id=%s&format=pdf&cpull=1"]
    (shell/sh "curl" "-u" "username:password" "http://wwwin-search.com/protected-cgi-bin/office2pdf.cgi" (format url id))))

(defn process-files
   "Take file name and read data"
   [file]
   (let [data (slurp file)
         rows (rest (c/parse-csv data))]
     (dorun
     (map #(println (call-curl (nth % 3 nil))) rows))))

(process-files "output.csv")

2 个答案:

答案 0 :(得分:2)

我怀疑第一个问题是因为没有println的代码看起来像:

(map (call-curl (nth % 3 nil)) rows)

而不是:

(map #(call-curl (nth % 3 nil)) rows)

如果您想仅为副作用而遍历整个序列,我建议doseq

(doseq [row rows]
  (call-curl (nth row 3 nil)))

或者,您可以使用run!

(run! call-curl (map #(nth % 3 nil)))

但我认为doseq版本更具可读性。

对于第二个问题,我认为您需要将curl调用的每个单独参数作为单独的字符串提供:它应该是

"-d" "..."

而不是

"-d ..."

我已经重构了一下以使其更具可读性:

(defn call-curl [id]
  (let [data (format "id=%s&format=pdf&cpull=1" id)]
    (shell/sh "curl" "-u" "username:password" "-d" data "http://wwwin-search.com/protected-cgi-bin/office2pdf.cgi")))

还有一点说明,根据您的代码,您没有在URL中传递参数,而是将数据作为请求体传递。来自man curl

  

-d, - data

     

(HTTP)将POST请求中的指定数据发送到HTTP服务器,就像用户拥有的浏览器一样。   填写HTML表单并按下提交按钮。这将导致   卷曲                     使用内容类型application / x-www-form-urlencoded将数据传递到服务器。与-F比较,   --form。

     

-d, - data与--data-ascii相同。 --data-raw几乎相同,但没有对@字符的特殊解释。要发布纯二进制数据,你   应改为使用--data-                     二元期权。要对表单字段的值进行URL编码,您可以使用--data-urlencode。

我不确定你为什么要调用curl而不是直接从Clojure调用HTTP端点,但现在当你评论说你确实想直接这样做时,我建议你使用{{3为此目的的库。在它的帮助下,它变得如此简单:

(require '[clj-http.client :as http])

(defn call-url [id]
  (http/post "http://wwwin-search.com/protected-cgi-bin/office2pdf.cgi"
    {:basic-auth ["username" "password"]
     :form-params {:id id
                   :format "pdf"
                   :cpull 1}}))

答案 1 :(得分:1)

这有帮助吗?

使用str而不是format,在某种程度上分配了对let块的渴望:

(shell/sh
   "curl" "-u" "username:password" "http://wwwin-search.com/protected-cgi-bin/office2pdf.cgi"
   "-d" (str "id=" id "&format=pdf&cpull=1"))

使用:out关键字返回call-curl的输出:

#((call-curl (nth % 3 nil)) :out)

修订代码:

(require '[clojure.java.shell :as shell])
(defn call-curl [id]
  (shell/sh
   "curl" "-u" "username:password" "http://wwwin-search.com/protected-cgi-bin/office2pdf.cgi"
   "-d" (str "id=" id "&format=pdf&cpull=1")))

(defn process-files
  "Take file name and read data"
  [file]
  (let [data (slurp file)
        rows (rest (c/parse-csv data))]
    (dorun
     (map #(do (prn %) (call-curl (nth % 3 nil)))
          rows))))

(process-files "output.csv")