Не удалось передать файлы cookie из Selenium webdriver в хранилище cookie httpclient в clojure

Я хочу использовать Selenium для входа на сайт, а затем экспортировать файл cookie в httpclient.

(defn convert-selemium-cookie-to-httpclient-cookie [x]
  (let [sf (SimpleDateFormat. "yyyy-MM-dd")
        fake-date (.parse sf "2018-08-06")]
    (doto
        (BasicClientCookie. (:name x) (:value x))
        (.setDomain (:domain x))
        (.setPath (:path x))
        (.setExpiryDate (if (:expiry x) (:expiry x) fake-date))
        (.setSecure (:secure? x)))))

(defn add-selenium-cookies-to-httpclient-cookie-store [x]
  (let [cs (clj-http.cookies/cookie-store)
        http-cookies (map convert-selemium-cookie-to-httpclient-cookie x)]
    (mapv (fn[x] (.addCookie cs x)) http-cookies)
    cs))

(def driver (new-driver {:browser :firefox}))
(def a (login driver ...)) ;; login
(def c (cookies driver)) ;; get the cookies
(def cs (add-selenium-cookies-to-httpclient-cookie-store c))
(println (client/get "some web site"
                     {:cookie-store cs
                      :client-params {"http.useragent"
                                      "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.20 (KHTML, like Gecko) Chrome/11.0.672.2 Safari/534.20"}}))

Несмотря на то, что я успешно вхожу в систему в webdriver, и этот сайт сохраняет файлы cookie через сеансы, после копирования файлов cookie в хранилище файлов cookie, client/get все еще возвращает страницу, не входящую в систему. Я пробовал аналогичную вещь на python и мог успешно перенести cookie от webdriver к запросам (http-клиент для python). Не уверен, где проблема для java/clojure.

Ответ 1

Вы не указали версии ваших зависимостей. Я проверил ваш код следующим образом:

[org.clojure/clojure "1.8.0"]
[clj-webdriver "0.7.2"]
[org.seleniumhq.selenium/selenium-server "3.0.0-beta4"]

Firefox 48.0.2
Mac OS Sierra 10.12

REPL сеанс в конце моего ответа показывает, что он работает (я использовал https://httpbin.org/ для его проверки).

Для устранения неполадок я бы поставил следующее:

  • распечатать, какие файлы cookie были возвращены из драйвера или проверить в консоли браузера, чтобы узнать, содержит ли ответ на вашей странице входа заголовки для установки правильных файлов cookie.
  • напечатайте, что содержит ваш http-client cookiestore.
  • включить ведение журнала отладки для http-client (или включить ведение журнала отладки на вашем сервере), чтобы узнать, какой фактический запрос отправлен на вашу страницу с защитой входа и если запрос содержит файлы cookie, установленные на странице входа.

В сеансе REPL вы можете видеть, что куки, возвращенные из селена, содержат куки, установленные первым запросом. Они также присутствуют в хранилище cookie http-client, и они правильно возвращаются URL-адресом https://httpbin.org/cookies, указывающим, что они были отправлены с запросом http-клиентом.

(require '[clj-webdriver.taxi :as taxi])
(require '[clj-http.client :as client])
(require '[clj-http.cookies :as cookies])
(require '[clojure.pprint :refer [pprint]])
(import java.text.SimpleDateFormat)
(import org.apache.http.impl.cookie.BasicClientCookie)

(defn convert-selemium-cookie-to-httpclient-cookie [x]
  (let [sf (SimpleDateFormat. "yyyy-MM-dd")
        fake-date (.parse sf "2018-08-06")]
    (doto
      (BasicClientCookie. (:name x) (:value x))
      (.setDomain (:domain x))
      (.setPath (:path x))
      (.setExpiryDate (if (:expiry x) (:expiry x) fake-date))
      (.setSecure (:secure? x)))))

(defn add-selenium-cookies-to-httpclient-cookie-store [x]
  (let [cs (cookies/cookie-store)
        http-cookies (map convert-selemium-cookie-to-httpclient-cookie x)]
    (mapv (fn [x] (.addCookie cs x)) http-cookies) cs))

(def cookie-name (str "c1" (System/currentTimeMillis)))
(def cookie-value (str "v1" (System/currentTimeMillis)))

(pprint cookie-name)
;; "c11475935066134"

(pprint cookie-value)
;; "v11475935066814"

(def driver (taxi/new-driver {:browser :firefox}))

(taxi/to driver (format "https://httpbin.org/cookies/set?%s=%s" cookie-name cookie-value))

(def selenium-cookies (taxi/cookies driver))

(pprint selenium-cookies)
;; #{{:cookie
;;    #object[org.openqa.selenium.Cookie 0x4dc96ce8 "c11475935066134=v11475935066814; path=/; domain=httpbin.org"],
;;    :name "c11475935066134",
;;    :value "v11475935066814",
;;    :path "/",
;;    :expiry nil,
;;    :domain "httpbin.org",
;;    :secure? false}}

(def http-client-cookie-store (add-selenium-cookies-to-httpclient-cookie-store selenium-cookies))

(pprint http-client-cookie-store)
;; #object[org.apache.http.impl.client.BasicCookieStore 0x6dfa86f5 "[[version: 0][name: c11475935066134][value: v11475935066814][domain: httpbin.org][path: /][expiry: Mon Aug 06 00:00:00 CEST 2018]]"]

(def http-client-response
  (client/get
    "https://httpbin.org/cookies"
    {:cookie-store http-client-cookie-store}))

(pprint http-client-response)
;; {:status 200,
;;  :headers
;;  {"Server" "nginx",
;;   "Date" "Sat, 08 Oct 2016 13:58:01 GMT",
;;   "Content-Type" "application/json",
;;   "Content-Length" "64",
;;   "Connection" "close",
;;   "Access-Control-Allow-Origin" "*",
;;   "Access-Control-Allow-Credentials" "true"},
;;  :body
;;  "{\n  \"cookies\": {\n    \"c11475935066134\": \"v11475935066814\"\n  }\n}\n",
;;  :request-time 1001,
;;  :trace-redirects ["https://httpbin.org/cookies"],
;;  :orig-content-encoding nil}