java爬虫教程:模拟用户表单登录

这个是爬虫教程第三篇,教大家如何模拟用户表单登录。

前期准备:

  • JSOUP 1.83 jar包
  • Eclipse 任意版本能运行java就行
  • 谷歌浏览器
第一步:依然是分析页面结构

我们要模拟CSDN用户表单登录,来获取用户登录后的数据。
在一些网站和论坛,部分内容总是需要会员用户等需要一定权限的用户才能看得到。
好了由此可见模拟用户表单登录的重要性了。

进入登录页,在页面上按F12查看页面元素的内容。

这次我们只要form标签,和其内部的账号密码输入框信息。

第二步:讲解一下Post需要的操作具体流程

一般表单的id都是唯一的,所以要过滤出表单是很容易的一件事情
这里表单的id值是fm1

1
List<Element> et = d1.select("#fm1");// 获取form表单

下一步是获得表单下面的帐号和密码输入框控件,同样可以根据id来过滤,不过这里使用的是name属性。
一般网站设计都会把name属性配上value,post到服务端。
直接在Map对象中put帐号和密码的键值对,代码如下

1
2
Map<String, String> datas = new HashMap<>();
datas.put(e.attr("name"), e.attr("value"));

这个就是表单的帐号密码输入框的键值
也可以不做遍历直接

1
2
datas.put("username", "your username");
datas.put("password", "your password");

哈哈,是不是少了许多。
经过这一步之后datas里已经存放了我们要post的数据了。
可以执行第二次请求将登录信息post上去了。
Response login = con2.ignoreContentType(true).method(Method.POST)
.data(datas).cookies(rs.cookies()).execute();
携带登录的Map数据和第一次登录返回的cookie,进行post。

第三步:开始写代码

好了就是这么简单。接下来看看代码吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.Connection.Method;
import org.jsoup.Connection.Response;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
/**
* 使用Jsoup模拟登陆CSDN
*
*
* 大体思路如下:
*
* 第一次请求登陆页面,获取页面信息,包含表单信息,和cookie(这个很重要),拿不到,会模拟登陆不上
*
*
* 第二次登陆,设置用户名,密码,把第一次的cooking,放进去,即可
*
* 怎么确定是否登陆成功?
*
* 登陆后,打印页面,会看到账户的详细信息。
*
*
* @date 2016年6月13日
* @author xiaolong
*
*
* **/
public class LoginDemo {
public static void main(String[] args) throws Exception {
LoginDemo loginDemo = new LoginDemo();
loginDemo.login("your account", "password");// 输入CSDN的用户名,和密码
}
/**
* 模拟登陆CSDN
*
* @param userName
* 用户名
* @param pwd
* 密码
*
* **/
public void login(String userName, String pwd) throws Exception {
// 第一次请求
Connection con = Jsoup
.connect("https://passport.csdn.net/account/login");// 获取连接
con.header("User-Agent",
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0");// 配置模拟浏览器
Response rs = con.execute();// 获取响应
Document d1 = Jsoup.parse(rs.body());// 转换为Dom树
List<Element> et = d1.select("#fm1");// 获取form表单,可以通过查看页面源码代码得知
// 获取,cooking和表单属性,下面map存放post时的数据
Map<String, String> datas = new HashMap<>();
for (Element e : et.get(0).getAllElements()) {
if (e.attr("name").equals("username")) {
e.attr("value", userName);// 设置用户名
}
if (e.attr("name").equals("password")) {
e.attr("value", pwd); // 设置用户密码
}
if (e.attr("name").length() > 0) {// 排除空值表单属性
datas.put(e.attr("name"), e.attr("value"));
}
}
/**
* 第二次请求,post表单数据,以及cookie信息
*
* **/
Connection con2 = Jsoup
.connect("https://passport.csdn.net/account/login");
con2.header("User-Agent",
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0");
// 设置cookie和post上面的map数据
Response login = con2.ignoreContentType(true).method(Method.POST)
.data(datas).cookies(rs.cookies()).execute();
// 打印,登陆成功后的信息
System.out.println(login.body());
// 登陆成功后的cookie信息,可以保存到本地,以后登陆时,只需一次登陆即可
Map<String, String> map = login.cookies();
for (String s : map.keySet()) {
System.out.println(s + " " + map.get(s));
}
}
}

总结

这个类中写了两次网站访问的请求
第一次请求用来获取cookie信息
第二次请求将携带cookie和登录数据的信息post出去用来模拟登录。
就是这么简单~~~

小Tips:
想要模拟用户表单登录,链接头信息是不可少的,"User-Agent"代表的是浏览器访问信息。
通过下图可以看到请求头可以有这么多的信息,
服务端可能会通过约束请求头来判别用户post/get的信息是否合法
所以请求头很重要~请求头很重要~请求头很重要~(重要的事情说三遍)

这个是登录后每一次操作都需要携带的头部信息。可以通过F12查看页面网络访问状态来查看请求头和返回头。
好啦,有了模拟表单登录了,是时候去大展身手了。
爬虫教程到此结束,希望有兴趣的小伙伴可以继续深入研究

By Xiaolong:You have a dream,you got to protect it!