【问题标题】:Session cookie not persisting with JSoup会话 cookie 不与 JSoup 保持一致
【发布时间】:2016-12-13 14:12:09
【问题描述】:

我一直在创建一个登录并抓取网站的 Android 应用。不幸的是,我遇到了 JSoup 和持久会话 cookie 的问题。

每当我尝试发出 POST 请求时,网站都会抱怨会话已过期。我已将问题的原因隔离到JSESSIONID cookie(因为在尝试登录时在浏览器上删除它会产生相同的结果)。但是,即使我使用.cookies() 方法包含所有以前的cookie,网站仍然会抱怨会话已过期。

我想知道我是否犯了任何明显的错误,导致我的应用无法正常维护会话。

到目前为止我的代码的相关部分(注意:我在这个项目中使用 Kotlin)

val url = "omitted here"
val username = "user"
val password = "hunter2"

val initial = Jsoup.connect(url)
            .method(Connection.Method.GET).execute()

val cookies = initial.cookies()

val login = Jsoup.connect(url)
            .userAgent("Mozilla")
            .data("login_name", username)
            .data("password", password)
            .cookies(cookies)
            .post()

任何帮助将不胜感激!

【问题讨论】:

  • 基于 cmets,这可能根本不是 Kotlin 问题,而是页面没有从服务器返回 cookie,而是稍后通过 JavaScript 返回。关闭 Web 浏览器中的 JavaScript,看看您是否仍然在 Web 浏览器中获得 cookie。如果不知道您尝试访问的页面,我认为我们无法做更多事情。但是我们会为您调试您的页面,而不是回答这个问题。

标签: android cookies jsoup kotlin


【解决方案1】:

假设 cookie 是由服务器设置而不是稍后通过 JavaScript 设置的,您的代码看起来是正确的。假设没有丢失代码,cookie 应该进入第二个请求。可能是您误解了站点的工作方式以及它如何使用 cookie,并且可能在登录之前它没有分配有效的 cookie,并且总是抱怨任何未登录的 cookie 上的“会话已过期”。也许根本不是代码错误,而是逻辑问题。

但如果您不考虑以下因素,您的完整代码也可能出错:

您需要记住,Jsoup 库仅在特定请求从服务器接收到 Set-Cookie 标头时才返回请求的 cookie。它确实返回“所有已知的cookies”列表。因此,您必须维护一个映射,该映射是每个 cookie 响应的持续累积。

response.cookies() 方法视为实际上是response.newCookiesAddedFromThisRequest()。代码模式是:

val cookies = mutableMapOf<String, String>()

val initialResponse = Jsoup.connect("http://www.whatarecookies.com/cookietest.asp")
    .method(Connection.Method.GET)
    .cookies(cookies)
    .execute()
cookies.putAll(initialResponse.cookies())

val secondResponse = Jsoup.connect("http://www.whatarecookies.com/cookietest.asp")
    .method(Connection.Method.GET)
    .cookies(cookies)
    .execute()
cookies.putAll(secondResponse.cookies()) 

// `cookies` now contains all cookies added accumulatively

在此代码中,每次将返回的新 cookie 添加到托管的 cookie 映射中,并且每次请求都会发送所有 cookie 的总数。

另请注意: Jsoup 不会按标题顺序处理 cookie,因此有时会为 cookie 设置错误的值。有时它也可能会在意外情况下将 cookie 值保留为 null。您应该检查 known cookie issues 的 Jsoup。另一种方法是使用OkHttp 之类的东西来检索文档,然后使用Jsoup 对其进行解析。 Jsoup 不像 HTML 解析和操作那样关注 HTTP 协议。

【讨论】:

  • 我已经尝试过你的代码解决方案和使用 OkHttp 来发出请求,但都没有骰子......我还尝试在我的表单 POST 之后向受保护资源添加另一个 GET 请求查看是否在事后设置了正确的 cookie,但这也没有奏效;我只能假设服务器在处理 cookie 时做了一些奇怪的事情
  • 如果它们是来自服务器的 cookie,您会以一种或另一种方式在 JSoup 中看到它们。它对过滤没有任何作用,只是将它们推到响应中。因此它们可能是 JavaScript 添加的 cookie。您可能需要使用服务器端抓取系统,该系统使用完整的浏览器来处理请求并在所有脚本完成后返回最终页面。那是完全不同的事情......
  • 我尝试使用 NoScript 登录该页面,并且效果很好……此时我完全不知所措,所以我将尝试 Selendroid(或者可能只使用 WebView)。不过,感谢您的帮助!
  • @cmdd 在使用 Chrome 或浏览器调试窗口时检查返回的标题,让您查看此类内容并查看返回的标题。这将是一个线索。从您的应用程序返回的标题也是如此,以查看它们是否不同。如果其他内容不“正确”,网站可能会阻止它?
  • 更新:出于好奇,我尝试使用Postman 向相关站点发送发布请求,使用其拦截器扩展来捕获确切的请求参数,就像在浏览器上登录时一样一般。提出请求后,我仍然收到相同的会话错误。 (旁注:我注意到通过浏览器登录将我重定向到另一个页面,然后将我留在“登录主页”,但是我尝试在我的 Jsoup 请求中设置 .followRequests(true) 并且没有骰子......
猜你喜欢
  • 2020-04-08
  • 2018-05-11
  • 2016-04-24
  • 2016-09-29
  • 1970-01-01
  • 2016-08-10
  • 2014-09-19
  • 2020-05-24
  • 2021-11-25
相关资源
最近更新 更多