会话cookie不与JSoup持久存​​在

时间:2016-08-07 20:48:25

标签: android cookies jsoup kotlin

我一直在创建一个登录并抓取网站的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()

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

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

但是,如果您不考虑以下事项,那么您的完整代码 也可能错误:

您需要记住,当该特定请求从服务器收到Set-Cookie标头时,Jsoup库仅返回请求的cookie。它返回“所有已知的cookie”列表。因此,您必须维护一个映射,该映射是每个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。您应该检查Jsoup的known cookie issues。另一种方法是使用OkHttp之类的东西来检索文档,然后使用Jsoup解析它。 Jsoup没有像在HTTP解析和操作上那样关注HTTP协议。