网络爬虫入门
一.网络爬虫
1.概述
- 网络爬虫也叫做网络机器人,可以代替人们自动地在互联网中进行数据信息的采集与整理
- 从功能上来讲,爬虫一般分为数据采集,处理,储存三个部分
- 既然是网络爬虫,自然离不开Http协议
- Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性
2.HttpClient
HttpClient有两个,分别是
org.apache.commons.httpclient.HttpClient
org.apache.http.client.HttpClient
前者现在是生命的尽头,不再被开发,被后者所替代
(1).commons包下的HttpClient
-
虽然commons包下的东西已经过时,不过我们了解下也没有什么坏处
-
commons包下的HttpClient是一个类
-
很多人觉得既然HttpClient是一个HTTP客户端编程工具,很多人把他当做浏览器来理解(这样理解只是为了更好的理解),但是其实HttpClient不是浏览器,它是一个HTTP通信库,因此它只提供一个通用浏览器应用程序所期望的功能子集,最根本的区别是HttpClient中没有用户界面,浏览器需要一个渲染引擎来显示页面,并解释用户输入
-
下面我们就以****登录页面来用HttpClient发送一个Get请求获取响应
A.Get请求
HttpClient httpclient = new HttpClient();//便于理解,可以理解为一个浏览器
GetMethod getMethod = new GetMethod("https://passport.****.net/account/login");//因为是Get请求
httpClient.executeMethod(getMethod); //提交,可以理解为我们按下回车
if(getMethod.getStatusLine().getStatusCode()==200) { //当响应码为200 即成功时
//获取转换为字符串的响应体
code = getMethod.getResponseBodyAsString();
}
B.Post请求
- 我们以模拟登录****为例子来进行访问
- 经抓包分析,post数据有三个是隐藏在登录页面上的,经过测试,fkid可以为空,所以只需要获取execution和lt的值就可以进行模拟登录了
- 先不考虑验证码的情况
private final String URL ="https://passport.****.net/account/login";//****登录网址
private HttpClient httpClient;//Get,Post请求都是一个HttpClient
private String lt,execution;//定义参数
public String getCsdnCode() throws Exception{
String code = null;
//因为是Get请求
GetMethod getMethod = new GetMethod(URL);
//提交,可以理解为我们按下回车
httpClient.executeMethod(getMethod);
//当响应码为200 即成功时
if(getMethod.getStatusLine().getStatusCode()==200) {
//获取转换为字符串的响应体
code = getMethod.getResponseBodyAsString();
}
return code;//返回响应体,即响应代码
}
public void postLoginCsdn() throws Exception{
httpClient = new HttpClient();
PostMethod postMethod = new PostMethod(URL);
String codes = getCsdnCode();
if(codes!=null) {
System.out.println("成功访问登录网址....................获取参数中................");
lt = search(codes,"name=\"lt\" value=\".+\"");//用正则获取页面代码的lt的属性
lt = lt.substring(lt.lastIndexOf('=')+2,lt.lastIndexOf('"'));
execution = search(codes,"name=\"execution\" value=\".+\"");//用正则获取页面代码的execution的属性
execution = execution.substring(execution.lastIndexOf('=')+2,execution.lastIndexOf('"'));
addparams(postMethod);//给Post请求设置参数
postMethod.setRequestHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");//设置请求头信息
Thread.sleep(10000);
//这里“休息”10s的原因在于,****后台好像做了验证
//如果在打开网页的瞬间就进行Post请求(登录),明显是机器,不是人在操作???博主是这样理解的
//如果不在这里做个延迟,会响应回一个登录太频繁了
httpClient.executeMethod(postMethod);//Post请求发送
if(postMethod.getStatusLine().getStatusCode() ==200 && postMethod.getResponseBodyAsString().indexOf("登录太频繁")==-1){
System.out.println(postMethod.getResponseBodyAsString());//打印响应体
System.out.println("登录成功");
}else {
System.out.println("登录失败");
}
}
}
private String search(String codes, String rex) {//正则
String result = null;
Pattern pattern = Pattern.compile(rex);
Matcher matcher = pattern.matcher(codes);
while(matcher.find()){
result = matcher.group();
}
return result;
}
private void addparams(PostMethod postMethod) {
postMethod.addParameter("gps", "");
postMethod.addParameter("username", "xxx");
postMethod.addParameter("password", "yyy");
postMethod.addParameter("rememberMe", "true");
postMethod.addParameter("lt", lt);
postMethod.addParameter("execution", execution);
postMethod.addParameter("fkid", "");
postMethod.addParameter("_eventId", "submit");
postMethod.addParameter("iframe", "false");
}
(2).apache包下的HttpClient
- apache包下的HttpClient是一个接口
A.Get请求
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet("https://passport.****.net/account/login");
CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
if(httpResponse.getStatusLine().getStatusCode()==200){
System.out.println(EntityUtils.toString(httpResponse.getEntity(),"UTF-8"));
}