我一直在创建一个Android应用程序,它可以登录和抓取一个网站。不幸的是,我在JSoup和持久化会话cookie方面遇到了问题。
每当我试图提出一个帖子请求,网站会抱怨会议已经过期。我已经将问题的原因隔离给了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()
任何帮助都将不胜感激!
发布于 2016-08-08 14:52:03
假设cookies是由服务器设置的,而不是稍后通过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添加到托管cookies地图中,并且每个请求发送所有cookies的全部内容。
还注意到: Jsoup不按头顺序处理cookie,因此有时会为cookie设置错误的值。它有时也会在意外事件中将cookie值保留为null。您应该检查已知的cookie问题中的Jsoup。另一种方法是使用类似于OkHttp的东西来检索文档,然后使用Jsoup解析它。对HTTP协议的关注不如对HTML解析和操作的关注。
https://stackoverflow.com/questions/38818416
复制相似问题