HttpClient 破解登陆带有验证码的网站拿到数据

        对于爬虫来说,验证码通常是实现过程中的一个巨大的障碍,因为验证码的多样性,有的甚至变态至极,所有一般来说使用代码自动识别验证码是非常困难的,本问的内容就是讲如何将验证码保存到本地,然后通过人工输入验证码实现登陆,从而抓取网页信息。

 

        首先说说整个登陆的流程,当我们打开一个网站的时候,浏览器就会记录该网站的cookie,用于识别信息,同时服务器会向浏览器发送一张验证码的图片,并与该cookie的信息是相关联的,并以此识别用户,然后post提交数据的时候一同提交就实现认证登陆了。

 

        以下登陆我们学校的教务处作为例子,这是我们教务处的登陆界面。

 

        右键打开chrome的审查元素,跟踪到验证码的链接。

 

 

        很明显"http://218.7.49.34/validateCodeAction.do?random=0.9378238802310079”,就是验证码的链接,其中中有个random=xxxxxxxxxxxxxxxxxxxxxxx的参数,实际上这个参数对于我们获取验证码和登陆是无关的,它只是为了防止浏览器把验证码页面缓存。其实“http://218.7.49.34/validateCodeAction.do”这样也是能获取验证码的,并且每次刷新都能得到不同的验证码,或者在“?random="后面个任意参数都能得到验证码,如图

        我最开始就以为random后面的那个数字是与登陆的信息相关了,导致我差点中途放弃,幸好后面遇到大神指点。在代码执行的过程中,首次打开登陆的页面,同时已经伴随着一张验证码的下载,因为在代码中一次无法同时访问两个链接,一个是登陆登陆页面的地址,一个是验证码的地址,所有我们在实际代码中应该先使用httpclient打开登陆的链接,这时httpclient会保存网站的cookie信息,所以我们在执行一次验证码的获取链接就能抓取到验证码了,然后保存到本地文件,输入其内容就能登陆网站了,

 

        然后我们用浏览器登陆一次,查看post请求中到底向服务器发送了那些数据,然后在代码中构造这些参数发送给服务器,模拟登陆,以下是我登陆我的账号显示的信息:

       

         这里写了一个client类,封装了打开网站,获取验证码和登陆功能,

public class Client {
    private String accout;
    private String password;
    HttpClient client = HttpClients.createDefault();//实例化httpclient
    HttpResponse response = null;
    String rawHtml;
    
    public Client(String accout, String password) {
        super();
        this.accout = accout;
        this.password = password;
    }
 
    public boolean login() {
        HttpGet getLoginPage = new HttpGet("http://218.7.49.34/loginAction.do");//教务处登陆页面get
        
        try {
            //打开教务处
            client.execute(getLoginPage);
            //获取验证码
            getVerifyingCode(client);
            
            //提醒用户并输入验证码
            System.out.println("verifying code has been save as verifyCode.jpeg, input its content");
            String code;
            Scanner in = new Scanner(System.in);
            code = in.nextLine();
            in.close();
            
            //设定post参数,和上图中的内容一致
            ArrayList<NameValuePair> postData = new ArrayList<NameValuePair>();
            postData.add(new BasicNameValuePair("zjh1", ""));
            postData.add(new BasicNameValuePair("tips", ""));
            postData.add(new BasicNameValuePair("lx", ""));
            postData.add(new BasicNameValuePair("eflag", ""));
            postData.add(new BasicNameValuePair("fs", ""));
            postData.add(new BasicNameValuePair("dzslh", ""));
            postData.add(new BasicNameValuePair("zjh", accout));//学号
            postData.add(new BasicNameValuePair("mm", password));//密码
            postData.add(new BasicNameValuePair("v_yzm", code));//验证码
            
            HttpPost post = new HttpPost("http://218.7.49.34/loginAction.do");//构建post对象
            post.setEntity(new UrlEncodedFormEntity(postData));//捆绑参数
            response = client.execute(post);//执行登陆行为
            rawHtml = EntityUtils.toString(response.getEntity(), "utf-8");
            System.out.println(rawHtml);
 
        } catch (ClientProtocolException e) {
            System.out.println(e.getMessage());
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }
    
    void getVerifyingCode(HttpClient client) {
        HttpGet getVerifyCode = new HttpGet("http://218.7.49.34/validateCodeAction.do");//验证码get
        FileOutputStream fileOutputStream = null;
        HttpResponse response;
        try {
            response = client.execute(getVerifyCode);//获取验证码
            /*验证码写入文件,当前工程的根目录,保存为verifyCode.jped*/
            fileOutputStream = new FileOutputStream(new File("verifyCode.jpeg"));
            response.getEntity().writeTo(fileOutputStream);
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
}

        主类代码

public class Main {
    public static void main(String[] args) {
        Client client = new Client("学号", "密码");
        client.login();
    }
}

   执行登陆操作

 

1、阿里云通用代金券,点击领取1888元
https://dwz.cn/zUx92TQa 
2、阿里云高性能服务器2折入口
https://dwz.cn/HYnDEWvY 
3、阿里云企业级性能云服务器限时2折
https://dwz.cn/uVBkhvQR   
4、【商标注册服务】低至300元
https://dwz.cn/hhsw8wq0  

5、最新【开年购季】特惠主会场
https://dwz.cn/d3DVIpdT   
6、【开年购季】云通信分会场
https://dwz.cn/d3DVIpdT 
7、【购物车】每满1000减50,最高可减5000
https://dwz.cn/PcHjcbH3 
8、阿里云【自营建站】限时优惠
https://dwz.cn/Cv5xCPM1

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值