网络爬虫入门

一.网络爬虫

1.概述

  • 网络爬虫也叫做网络机器人,可以代替人们自动地在互联网中进行数据信息的采集与整理
  • 从功能上来讲,爬虫一般分为数据采集,处理,储存三个部分
  • 既然是网络爬虫,自然离不开Http协议
  • Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性

2.HttpClient

HttpClient有两个,分别是
org.apache.commons.httpclient.HttpClient
org.apache.http.client.HttpClient
前者现在是生命的尽头,不再被开发,被后者所替代
(1).commons包下的HttpClient

HttpClient所需要jar包.

  • 虽然commons包下的东西已经过时,不过我们了解下也没有什么坏处

  • commons包下的HttpClient是一个类

  • 很多人觉得既然HttpClient是一个HTTP客户端编程工具,很多人把他当做浏览器来理解(这样理解只是为了更好的理解),但是其实HttpClient不是浏览器,它是一个HTTP通信库,因此它只提供一个通用浏览器应用程序所期望的功能子集,最根本的区别是HttpClient中没有用户界面,浏览器需要一个渲染引擎来显示页面,并解释用户输入

  • 下面我们就以csdn登录页面来用HttpClient发送一个Get请求获取响应

A.Get请求
               HttpClient httpclient = new HttpClient();//便于理解,可以理解为一个浏览器
                GetMethod getMethod = new GetMethod("https://passport.csdn.net/account/login");//因为是Get请求
                httpClient.executeMethod(getMethod);                //提交,可以理解为我们按下回车
              if(getMethod.getStatusLine().getStatusCode()==200) {             //当响应码为200 即成功时
                    //获取转换为字符串的响应体
                    code = getMethod.getResponseBodyAsString();
                }
B.Post请求
  • 我们以模拟登录csdn为例子来进行访问
  • 经抓包分析,post数据有三个是隐藏在登录页面上的,经过测试,fkid可以为空,所以只需要获取execution和lt的值就可以进行模拟登录了
  • 先不考虑验证码的情况
    网络爬虫入门
  		private final String URL ="https://passport.csdn.net/account/login";//csdn登录网址

           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的原因在于,csdn后台好像做了验证
                    //如果在打开网页的瞬间就进行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.csdn.net/account/login");
        CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
        if(httpResponse.getStatusLine().getStatusCode()==200){
            System.out.println(EntityUtils.toString(httpResponse.getEntity(),"UTF-8"));
        }
B.Post请求