Gal*_*ude 1 clojure jsoup clojure-java-interop
我不想刮一个网站,这需要我登录.我决定用Jsoup来做这件事.我无法正确地将这行代码"翻译"到Clojure:
Connection.Response loginForm = Jsoup.connect("**url**")
.method(Connection.Method.GET)
.execute();
Run Code Online (Sandbox Code Playgroud)
如果没有Connection.Response在我的Clojure代码中指定类,则连接具有类jsoup.helper.HttpConnect,该类缺少会话中的cookie所需的方法.
到目前为止,我已经提出了以下Clojure代码:
(import (org.jsoup Jsoup Connection
Connection$Response Connection$Method))
(do
(def url "*URL*")
(def res (doto (org.jsoup.Jsoup/connect url)
(.data "username" "*USERNAME*")
(.data "password" "*PASSWORD")
(.method Connection$Method/POST)
(.execute)))
(type res))
Run Code Online (Sandbox Code Playgroud)
问题是你在使用线程宏的doto地方使用->:
(let [url "*URL*"]
(-> url
(org.jsoup.Jsoup/connect)
(.data "username" "*USERNAME*")
(.data "password" "*PASSWORD*")
(.method "Connection$Method/POST)
(.execute)))
Run Code Online (Sandbox Code Playgroud)
doto当您需要设置一个Java对象时,通常会使用表单,该对象提供类似于setter的方法,void并且会阻止您使用线程.
(doto (SomeClass.)
(.setA 1)
(.setB 2)
(.execute))
Run Code Online (Sandbox Code Playgroud)
翻译成:
(let [obj (SomeClass.)]
(.setA obj 1)
(.setB obj 2)
(.execute obj)
obj)
Run Code Online (Sandbox Code Playgroud)
如您所见doto,不会返回最后一个方法调用的结果,而是返回作为其第一个参数提供的对象(SomeClass在本例中为object).因此,您当前的代码返回Jsoup/connect方法创建的对象(jsoup.helper.HttpConnect如您所注意到的),而不是方法调用的Connection.Response结果execute().
你需要的是:
(-> (SomeClass.)
(.withA 1)
(.withB 2)
(.execute))
Run Code Online (Sandbox Code Playgroud)
with*返回的构建器方法在哪里this而不是void.
以上线程表相当于:
(.execute
(.withB
(.withA
(SomeClass.)
1)
2))
Run Code Online (Sandbox Code Playgroud)