利用Jsoup模拟跳过登录爬虫获取数据
今天在学习爬虫的时候想着学习一下利用jsoup模拟登录。下面分为有验证码和无验证码的情况进行讨论。
---------------------------无验证码的情况----------------------------
1.我们正常利用网页进行登录,利用浏览器自带的开发者工具查看一些登录信息
我们登录的时候需要携带自己的身份信息,也就是用户名和密码。也会携带一些浏览器的信息,所以我们可以通过Jsoup伪造一些请求头,并写到自己的身份信息去登录,然后获取登录后返回的cookie,cookie中会包含session,有了sessionid我们就可以爬取登录之后可以访问的url。
2.Jsoup伪造请求头且携带身份信息获取登录信息
/** * 模拟登录获取cookie和sessionid */ public static void login() throws IOException { String urlLogin = "http://qiaoliqiang.cn/Exam/user_login.action"; Connection connect = Jsoup.connect(urlLogin); // 伪造请求头 connect.header("Accept", "application/json, text/javascript, */*; q=0.01").header("Accept-Encoding", "gzip, deflate"); connect.header("Accept-Language", "zh-CN,zh;q=0.9").header("Connection", "keep-alive"); connect.header("Content-Length", "72").header("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); connect.header("Host", "qiaoliqiang.cn").header("Referer", "http://qiaoliqiang.cn/Exam/"); connect.header("User-Agent", "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36") .header("X-Requested-With", "XMLHttpRequest"); // 携带登陆信息 connect.data("username", "362501197407067215").data("password", "123456").data("user_type", "2") .data("isRememberme", "yes"); //请求url获取响应信息 Response res = connect.ignoreContentType(true).method(Method.POST).execute();// 执行请求 // 获取返回的cookie Map<String, String> cookies = res.cookies(); for (Entry<String, String> entry : cookies.entrySet()) { System.out.println(entry.getKey() + "-" + entry.getValue()); } System.out.println("---------华丽的分割线-----------"); String body = res.body();// 获取响应体 System.out.println(body); }
结果:
logininfo-"362501197407067215,123456"
JSESSIONID-75ad3bad-30cd-4d7a-8918-b13054f4b737
rememberMe-deleteMe
---------华丽的分割线-----------
{"login_result":"success_manager","user_type":"2","login_url":"examParper\/examPaper\/examparperManage.jsp"}
反例:
此时我们将身份信息的密码改成错误密码:
// 携带登陆信息 connect.data("username", "362501197407067215").data("password", "123").data("user_type", "2") .data("isRememberme", "yes");
结果:
---------华丽的分割线----------- {"login_result":"error002","user_type":"2","login_url":null}
3.在上述获取cookie的基础上模拟访问网站登录可以访问的网址
将cookies定义为一个全局变量cookies,当我们访问登录可以访问的url的时候带着cookies去访问。
package cn.qlq.craw.Jsoup; import java.io.IOException; import java.util.Map; import java.util.Map.Entry; import org.jsoup.Connection; import org.jsoup.Connection.Method; import org.jsoup.Connection.Response; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; /** * 模拟Jsoup跳过登陆进行爬虫 * * @author liqiang * */ public class JsoupCookieCraw { private static Map<String, String> cookies = null; public static void main(String[] args) throws IOException { // 先模拟登录获取到cookie和sessionid并存到全局变量cookies中 login(); String url = "http://qiaoliqiang.cn/Exam/view/testPerson/outEmployeeAllot.jsp"; // 直接获取DOM树,带着cookies去获取 Document document = Jsoup.connect(url).cookies(cookies).post(); System.out.println(document.toString()); } /** * 模拟登录获取cookie和sessionid */ public static void login() throws IOException { String urlLogin = "http://qiaoliqiang.cn/Exam/user_login.action"; Connection connect = Jsoup.connect(urlLogin); // 伪造请求头 connect.header("Accept", "application/json, text/javascript, */*; q=0.01").header("Accept-Encoding", "gzip, deflate"); connect.header("Accept-Language", "zh-CN,zh;q=0.9").header("Connection", "keep-alive"); connect.header("Content-Length", "72").header("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); connect.header("Host", "qiaoliqiang.cn").header("Referer", "http://qiaoliqiang.cn/Exam/"); connect.header("User-Agent", "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36") .header("X-Requested-With", "XMLHttpRequest"); // 携带登陆信息 connect.data("username", "362501197407067215").data("password", "123456").data("user_type", "2") .data("isRememberme", "yes"); //请求url获取响应信息 Response res = connect.ignoreContentType(true).method(Method.POST).execute();// 执行请求 // 获取返回的cookie cookies = res.cookies(); } }
结果:(可以获取到我们访问的页面的内容)
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>分配员工</title>
.....................
反例:
我们将登录方法去掉,同时访问的时候不携带cookies:
public static void main(String[] args) throws IOException { String url = "http://qiaoliqiang.cn/Exam/view/testPerson/outEmployeeAllot.jsp"; // 直接获取DOM树,带着cookies去获取 Document document = Jsoup.connect(url).post(); System.out.println(document.toString()); }
结果:(我们访问到的是系统的主页,也就是登录界面,发现我们被拦在网站外面)
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>主页</title>
.....
总结:
不带验证码的登录利用上面的模拟登录的方法基本能满足要求。
---------------------------带验证码的情况----------------------------
【当你用心写完每一篇博客之后,你会发现它比你用代码实现功能更有成就感!】