会话cookie不会与JSoup保持一致

我一直在创建一个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() 

任何帮助将不胜感激!

您的代码看起来正确,假设Cookie由服务器设置,而不是稍后通过JavaScript设置。 假设没有丢失的代码,cookies应该进入第二个请求。 这可能是因为你误解了网站的工作原理以及它如何使用cookies,也许它不会在登录之前分配一个有效的cookie,并总是抱怨任何未登录的cookie上的“session expired”。 也许不是一个代码错误,而是一个逻辑问题。

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

您需要记住,当特定请求从服务器接收到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值留空。 你应该检查Jsoup 已知的cookie问题 。 另一种方法是使用类似OkHttp的方法来检索文档,然后使用Jsoup进行解析。 Jsoup没有像在HTML解析和操作上那样关注HTTP协议。