流程是获取验证码,返回的cookie用存到session中,再模拟登录的时候,帐号+密码+cookie+验证码带过去登录。但是返回的json总是提示没有输入验证码,估计是网站识别不了带过去的cookie。因为我用模拟登录的时候,在手动输入cookie中持有的sessionid类似标识信息过去时,在正确时能登录。在错误时也是提示没有输入验证码。
请问为什么会出现这种情况,我前面保存的cookie为什么在后面带过去的时候不能用了?困扰许久,请帮忙!谢谢谢谢!
首先 获取验证码的代码
public static Map<String, Object> getCheckImg(String checkUrl, Map<String, String> data, Map<String, String> cookies, boolean tls, boolean conType, boolean redirects) {
try {
Map<String, Object> map = new HashMap<String, Object>();
System.out.println("checkUrl"+checkUrl+"-----data:"+data);
Response res = installConnection(Jsoup.connect(checkUrl), data, cookies, tls, conType, redirects).method(Method.GET).timeout(20000).execute();
InputStream in_nocode = new ByteArrayInputStream(res.bodyAsBytes());
System.out.println("放进去的cookie"+res.cookies());
map.put("cookie", res.cookies());
map.put("imgIO", ImageIO.read(in_nocode));
return map;
} catch (IOException e) {
loger.error("获取验证码失败!" + e);
}
return null;
}
----------------------------------封装jsoup的connection代码
private static Connection installConnection(Connection con, Map<String, String> data, Map<String, String> cookies, boolean tls, boolean conType, boolean redirects) {
if (tls) {
con.validateTLSCertificates(false);
}
if (conType) {
con.ignoreContentType(true);
}
if (redirects) {
con.followRedirects(false);
}
if (cookies != null) {
con.cookies(cookies);
}
if (data != null) {
con.data(data);
}
return con;
}
-------进行登录的代码
private boolean crawlJobcn(int userAccountId, int userClass, String time, HashMap<String, String> propertiesMap) throws IOException {
Map<String, String> map = new HashMap<String, String>();
Map<String, String> checkCooikis = (Map<String, String>) request.getSession().getAttribute("checkCookie");
System.out.println(checkCooikis);
map.put(propertiesMap.get("zhuobo_CheckCode"), validateCode);
map.put(propertiesMap.get("zhuobo_Login_Name"), loginName);
map.put(propertiesMap.get("zhuobo_Login_Pwd"), loginPwd);
Response responseJsoup = CrawlUtils.login(map, checkCooikis, propertiesMap.get("zhuobo_Login_Url"), Method.POST, true, true, false);
}
public static Response login(Map<String, String> data, Map<String, String> cookies, String loginUrl, Method method, boolean tls, boolean conType, boolean redirects) {
try {
System.out.println("带过去的cookie:"+cookies+",data:"+data+",loginUrl:"+loginUrl+",tls:"+tls);
Response response = installConnection(Jsoup.connect(loginUrl), data, cookies, tls, conType, redirects).method(method).timeout(20000).execute();
if (response.statusCode() == 200) {
return response;
}
} catch (Exception e) {
loger.error("抓取简历登陆时,网络存在问题,请检查网络!" + e);
}
return null;
}
既然人家返回说没有输入验证码,那就说明你的验证码的字段名可能传错了
确定没错哦,当我用手动通过浏览器获得验证码,通过看头部复制那个sessionid,然后用模拟器去手动提交时,就可以。但是我用jsoup connection 验证码地址返回的cookie,在模拟登录时带上这个cookie。就一直提示验证码没有输入。但我确定是有带过去的。而且字段名没错. 所以我认为他们网站的机制时,先看sessionid,有效才会验证验证码。否则就是直接报需要输入验证码。
@前进路上: 你说的有道理,估计是你cookie的存储方式有问题
@刘宏玺: System.out.println("放进去的cookie"+res.cookies());
你这句话输出的是你获取验证码后的cookie
你要看看你调用的时候有没有设置好cookie
你输出这个看看你调用前的cookie是啥System.out.println("调用前的cookie"+cookies);
@刘宏玺:
放进去的cookie{JCNID=jcnp60239931567989e4af90}
{JCNID=jcnp60239931567989e4af90}
带过去的cookie:{JCNID=jcnp60239931567989e4af90},data:{userName=liuminyi , password=123456, randomCode=1234},loginUrl:http://www.jobcn.com/person/login_action.ujson?_t=,tls:true
@前进路上: 你看看我说的调用前的cookie是啥?
System.out.println("调用前的cookie"+cookies);
@刘宏玺: 那句输出 带过去的cookie 就是对connection进行封装时的语句,也就是带过去的cookie
@前进路上: -------进行登录的代码 这个代码看不出来调用关系,你还是在句代码后面加上我说的那句代码,看看结果吧
System.out.println("放进去的cookie"+res.cookies());
System.out.println("调用前的cookie"+cookies);
@刘宏玺: 请问您指的是 Response responseJsoup = CrawlUtils.login(map, checkCooikis, propertiesMap.get("zhuobo_Login_Url"), Method.POST, true, true, false); 之后输出吗?
我在之后写
Map<String, String> cookies = responseJsoup.cookies();
System.out.println("登录完的cookie"+cookies);
结果是空。
@前进路上:
public static Map<String, Object> getCheckImg(String checkUrl, Map<String, String> data, Map<String, String> cookies, boolean tls, boolean conType, boolean redirects) { try { Map<String, Object> map = new HashMap<String, Object>(); System.out.println("checkUrl"+checkUrl+"-----data:"+data); Response res = installConnection(Jsoup.connect(checkUrl), data, cookies, tls, conType, redirects).method(Method.GET).timeout(20000).execute(); InputStream in_nocode = new ByteArrayInputStream(res.bodyAsBytes()); System.out.println("放进去的cookie"+res.cookies());
System.out.println("调用前的cookie"+cookies); map.put("cookie", res.cookies()); map.put("imgIO", ImageIO.read(in_nocode)); return map; } catch (IOException e) { loger.error("获取验证码失败!" + e); } return null; }
看第一段代码,把我的那句话加到那里,也就是要看看你组装请求登录的cookie是啥
@刘宏玺: 这句是获取验证码的代码哦,url请求的地址也是获取验证码的地址,在第一次获取验证码之前,我是不带cookie过去的,也就是null。也就是这句
if ("zhuobo".equals(crawlForm)) {
map = CrawlUtils.getCheckImg(propertiesMap.get(crawlForm + "_Check_Url"), null, null, false, true, false);
}
@前进路上: 那login方法是谁调用的呢?调用的时候cookie是否有效呢?
@刘宏玺: 我前台输入帐号密码验证码,后台封装帐号密码加验证码以及带上之前存在session中的cookie,在封装login的connection登录请求时,带上他们进行提交到目标地址,模拟登录呀,时间应该很快,所以应该不会是时效问题吧?
@前进路上: 你在调用前输出下cookie不就知道是否有效了么你用到cookie的地方都输出一下,看看所有的cookie是否都是同样的,你要做到保持一致,估计问题就解决了
@刘宏玺: 嗯 我再看看吧。还是谢谢您
@刘宏玺 我好像找到问题了。但是我不明白为什么?请您帮我分析下,这分数就给您了。
我自己修改了下,取的cookie的地址。一开始我写的是验证码返回的cookie。
也就是这个:http://www.jobcn.com/person/loginrandomCode.xhtml
但是这个cookie,一直失效,用不了。
刚无意改成了 http://www.jobcn.com 也就是根站点,取回来的cookie,再去登录时。
发现竟然成功了!我想问下同个站点下的给出的sessionid有可能会不同吗?该不会是因为分布式服务器搞得我sessionid不共享,一直拿着不同服务器的sessionid进行访问吧?有这种可能吗?
@前进路上: 就算是分布式服务器,也会使用同一个session,不然用户岂不是要经常重新登录,估计是验证登录的地方规定了必须是访问过根站点的session才可以验证通过
看不太懂你的問題,但jsonp請求預設是不帶cookie的,不知道是不是你要問的
域名不同是不能共用cookie的吧。。
我用jsonP的时候是直接URL参数
同个站点的。
楼主,你好,我的问题是:第一次登录成功后,可以得到cookies;之后,带着这个cookies去访问链接(必须登录才能访问到的,如果没有登录就会调到登录页面),不能成功就去,还是跑到登录页面;
另外:我通过浏览器成功登录该网站,通过浏览器得到cookies值,拷贝到代码里面,运行,直接都可以访问链接(这个链接是必须登录成功才可以访问的,这里不需要登录了)
一直解决不了,为啥?