canonical - Clojure construyendo URL a partir de partes constituyentes
canonical url (5)
Aquí hay una forma:
user=> (import [java.net URLEncoder])
java.net.URLEncoder
user=> (str "http://stackoverflow.com/search?q=" (URLEncoder/encode "clojure url" "UTF-8"))
"http://stackoverflow.com/search?q=clojure+url"
Sin embargo, sé que esto no es exactamente lo mismo que tu fragmento de Python. Consulte la siguiente publicación de la lista de correo de Clojure para obtener una respuesta más completa:
http://www.mail-archive.com/[email protected]/msg29338.html
El código de allí te permitirá hacer esto:
user=> (encode-params {"q" "clojure url"})
"q=clojure+url"
En Python, haría lo siguiente:
>>> q = urllib.urlencode({"q": "clojure url"})
>>> q
''q=clojure+url''
>>> url = "http://stackoverflow.com/search?" + q
>>> url
''http://stackoverflow.com/search?q=clojure+url''
¿Cómo hago toda la codificación que se hace para mí arriba en Clojure? En otras palabras, ¿cómo hago algo similar a lo siguiente?
=> (build-url "http://stackoverflow.com/search" {"q" "clojure url"})
"http://stackoverflow.com/search?q=clojure+url"
Hay una función de url-encode
en el espacio de nombres ring.util.codec
de Ring:
(ring.util.codec/url-encode "clojure url")
; => "clojure+url"
No estoy seguro de si hay una función preempaquetada para convertir un mapa en una cadena de consulta, pero quizás esto podría hacer el trabajo:
(use ''[ring.util.codec :only [url-encode]])
(defn make-query-string [m]
(->> (for [[k v] m]
(str (url-encode k) "=" (url-encode v)))
(interpose "&")
(apply str)))
Un ejemplo:
user> (make-query-string {"q" "clojure url" "foo" "bar"})
"q=clojure+url&foo=bar"
Lo único que queda es concatenar el resultado al final de una URL:
(defn build-url [url-base query-map]
(str url-base "?" (make-query-string query-map)))
Parece funcionar:
user> (build-url "http://.com/search" {"q" "clojure url"})
"http://.com/search?q=clojure+url"
Actualizar:
Quizás una versión modificada podría hacer una experiencia más amigable con Clojure. También maneja la codificación a través de un argumento opcional estilo anillo con utf-8 como predeterminado.
(defn make-query-string [m & [encoding]]
(let [s #(if (instance? clojure.lang.Named %) (name %) %)
enc (or encoding "UTF-8")]
(->> (for [[k v] m]
(str (url-encode (s k) enc)
"="
(url-encode (str v) enc)))
(interpose "&")
(apply str))))
(defn build-url [url-base query-map & [encoding]]
(str url-base "?" (make-query-string query-map encoding)))
Entonces ahora podemos hacer
user> (build-url "http://example.com/q" {:foo 1})
"http://example.com/q?foo=1"
clj-apache-http es bastante útil. Con él puedes hacer lo siguiente:
user=> (require [''com.twinql.clojure.http :as ''http])
nil
user=> (def q (http/encode-query {"q" "clojure url"}))
#''user/q
user=> (def url (str "http://.com/search?" q))
#''user/url
user=> url
"http://.com/search?q=clojure+url"
Una solución simple que usa str (ings):
(def q (str "clojure+url"))
(def url (str "http://.com/search?" q))
Este es el equivalente REPL exacto de su sesión de python, usando clj-http .
user=> (require [''clj-http.client :as ''client])
nil
user=> (str "http://.com/search?"
user=* (client/generate-query-string {"q" "clojure url"}))
"http://.com/search?q=clojure+url"
pero clj-http lo hace aún más fácil:
user=> (client/get "http://.com/search?"
user=* {:query-params {"q" "clojure url"}})
... <a lot of output, omitted to protect the innocent>...
suponiendo que quiera realizar una solicitud GET, eso es.