前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java数据采集-8.模拟登录

Java数据采集-8.模拟登录

作者头像
geekfly
发布2022-05-06 19:40:06
5060
发布2022-05-06 19:40:06
举报
文章被收录于专栏:geekflygeekfly

登录网址:https://passport.csdn.net/account/login?ref=toolbar 项目源码:https://github.com/geekfly2016/Spider 代码目录:Spider/src/xyz/geekfly/csdn/Login.java

当我们对某些网站进行一些特定操作时,如知乎的点赞,会要求我们登录,这时候一些简单的做法就是粘贴浏览器请求中的Cookie信息,但作为自动化的程序来讲,这个方法明显不可行。因此就有了模拟登录的需求。 注:至于Cookie是什么,在网页请求时有什么用,不在本文讨论范围,自行Google吧。


模拟登录一般分为以下几步:

  1. 获取登录的所需的信息
  2. 模拟提交账号信息,获取Cookie
  3. 携带Cookie进行目标操作

以CSDN登录为例,详细介绍每一步如何操作和代码实现: 1. 获取登录的所需的信息 打开CSDN,点击登录,即可看到登录页面,打开开发者工具。

这里写图片描述
这里写图片描述

注意先清空列表,勾选Preserve log(保持日志),这样点击登录跳转之后才能记录之前的请求。


输入自己的账号密码,点击登录,在第一个请求中我们可以看到登录请求所携带的参数,包括我们输入的用户名(username)和密码(password),但是发现还有几个其它参数。

这里写图片描述
这里写图片描述

再次退出,点击登录,查看表单发现存在这几个参数,因此模拟登录前需要获取这些参数。

这里写图片描述
这里写图片描述

方案是模拟登录前,先访问https://passport.csdn.net/account/login?ref=toolbar登录页面,使用Jsoup获取三个隐藏参数和表单提交的action(即为模拟登录的Url),保存以供下一步使用。 代码如下:

代码语言:javascript
复制
public static Map<String, String> getLoginInfo(){
        String login_url = "https://passport.csdn.net/account/login?ref=toolbar";
        String login_host = "https://passport.csdn.net"; //表单中获取的登录地址不带域名,需自行添加,拼接域名需注意‘/’,不要多加或漏加
        Map<String, String> return_data = new HashMap<String, String>();

        try {
            Document document = Jsoup.connect(login_url) 
                    .userAgent("ozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36") 
                    .get();
            //获取登录的表单
            Elements element = document.select("#fm1");
//          System.out.println(element);

            //获取登录所需要的一些参数
            return_data.put("lt", element.select("input[name=lt]").attr("value"));//登录流水号
            return_data.put("execution", element.select("input[name=execution]").attr("value"));
            return_data.put("_eventId", element.select("input[name=_eventId]").attr("value"));

            //获取点击登录的请求地址
            return_data.put("action", login_host + element.attr("action"));
        }catch (IOException e) {
            e.printStackTrace();
        }
        return return_data;
    }

获取到的数据样例:

代码语言:javascript
复制
{   _eventId=submit,              action=https://passport.csdn.net/account/login;jsessionid=092BDD9C93EF4EE91917E080BE78981F.tomcat2?ref=toolbar, 
    lt=LT-508266-gPApMyjqezncjwuO3e02HDefS3Faa3,
    execution=e1s1
}

对于有些网站在分析之后,登录仅需要模拟点击登录所请求的Url带上用户信息即可,没有需要从登录页面获取参数的网站,不需要访问登录页面,只要找到模拟登录的Url即可。

2. 模拟提交账号信息,获取Cookie 在上一步点击登录后,可以在Response Headers中发现后台返回了很多参数,而在之后请求中,主要用到的也就是Cookie了,因此需要提取Cookie,而返回的又有很多个,需要自行拼接。

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

代码如下:

代码语言:javascript
复制
public static String getCookie(Map<String, String> data){
        String cookie = "";
        try{
            HttpClient httpClient = new DefaultHttpClient();

            HttpPost post = new HttpPost(data.get("action"));
            /* 模拟登录所需要的参数,有些网站登录时会检测,
                如果存在基本上为必须,但CSDN发现并没有检测,故没有添加
                在Chrome开发者平台中可查看,粘贴过来即可
             */
//          post.setHeader("Host", "passport.csdn.net");
//          post.setHeader("Referer","https://passport.csdn.net/account/login?ref=toolbar");
//          post.setHeader("Origin", "https://passport.csdn.net");
//          post.setHeader("Content-Type","application/x-www-form-urlencoded");

            List<NameValuePair> params = new ArrayList<NameValuePair>();  

            //参数
            params.add(new BasicNameValuePair("lt", data.get("lt"))); 
            params.add(new BasicNameValuePair("execution", data.get("execution")));
            params.add(new BasicNameValuePair("_eventId", data.get("_eventId"))); 

            //用户名和密码(*号),替换为自己的
            params.add(new BasicNameValuePair("username", "******")); 
            params.add(new BasicNameValuePair("password", "*******"));

            post.setEntity(new UrlEncodedFormEntity(params,Consts.UTF_8));  
            HttpResponse response = httpClient.execute(post);
            int statusCode = response.getStatusLine().getStatusCode();
            if(statusCode != 200){
                System.out.print(statusCode);
            }
            Header[] map =  response.getAllHeaders();

            //如需查看所有的响应头,取消以下注释即可  
            /*System.out.println("显示响应Header信息\n");
            for (Header entry : map)
            {
                System.out.println("Key : " + entry.getName() + " ,Value : " + entry.getValue());
            }*/

            //对于登录,主要为获取响应头中的Cookie信息,拼接Cookie
            for (Header entry : map)
            {
                if(entry.getName().contains("Set-Cookie")){
                    cookie += entry.getValue() + ";";
                }
            }
            System.out.println("Cookie信息:" + cookie);
        }catch (Exception e) {
            e.printStackTrace();
        }
        return cookie;
    }

3. 携带Cookie进行目标操作 在后续请求中,携带Cookie即可。

代码语言:javascript
复制
public static String getData(String target_url, String cookie){
        String result = null;
        try{
            HttpClient httpClient = new DefaultHttpClient();

            HttpGet httpGet = new HttpGet(target_url);

            //传入Cookie信息
            httpGet.setHeader("Cookie", cookie);

            HttpResponse response = httpClient.execute(httpGet);
            int statusCode = response.getStatusLine().getStatusCode();
            if(statusCode != 200){
                System.out.print(statusCode);
            }
            HttpEntity entity = response.getEntity();

            if (entity != null) {
                result = EntityUtils.toString(entity, "utf-8");
            }

        }catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

主函数调度代码:

代码语言:javascript
复制
public static void main(String[] args) {
        //1. 获取登录所需的信息
        Map<String, String> login_info = getLoginInfo();

        //2. 模拟登录获取Cookie
        String cookie = getCookie(login_info);
        //3. 携带Cookie访问目标页(换成自己的)
        String target_url = "http://blog.csdn.net/tmaskboy";

        //携带登录获取的Cookie
        String result = getData(target_url, cookie);
        Document document = Jsoup.parse(result);
        System.out.println("携带Cookie:" + document.select(".navigator").text());

        //未携带Cookie
        String result1 = getData(target_url, "");
        Document document1 = Jsoup.parse(result1);
        System.out.println("未携带Cookie:" + document1.select(".navigator").text());
    }

运行演示:

代码语言:javascript
复制
Cookie信息:CASTGC=TGT-147082-YbG1A3MxGJHOZTDoHerLF9uAAbE6xiw2tKxc95RszTJ53OdE6U-passport.csdn.net; Path=/; Secure;UserName=TMaskBoy; Domain=.csdn.net; Path=/;UserInfo=NO45ahI1532jJLeoAla%2FybWeLRchb6M4TE4Hy5%2B%2FYjgBdIsumoYTKx%2FLZHKTQ1QUgmGrCjbEmwLO53SS6yLYwKp25%2BKY62REyhgEe3HX2drygMQJuAyjq7%2FYKrZG7tUJ; Domain=.csdn.net; Path=/;UserNick=geekfly; Domain=.csdn.net; Path=/;AU=2DB; Domain=.csdn.net; Path=/;UD=%E5%94%AF%E6%9C%89%E5%89%B2%E8%88%8D%EF%BC%8C%E6%89%8D%E8%83%BD%E4%B8%93%E6%B3%A8%E3%80%82%E5%94%AF%E6%9C%89%E6%94%BE%E5%BC%83%EF%BC%8C%E6%89%8D%E8%83%BD%E8%BF%BD%E6%B1%82%E3%80%82; Domain=.csdn.net; Path=/;UN=TMaskBoy; Domain=.csdn.net; Expires=Mon, 15-Oct-2018 09:09:30 GMT; Path=/;UE="geekfly@126.com"; Version=1; Domain=.csdn.net; Max-Age=31536000; Expires=Mon, 15-Oct-2018 09:09:30 GMT; Path=/;BT=1508058570894; Domain=.csdn.net; Expires=Mon, 15-Oct-2018 09:09:30 GMT; Path=/;access-token=65d8afcc-f6ee-44b2-afca-5d2dbed642f6; Domain=.csdn.net; Path=/;
携带Cookie:目录视图 摘要视图 订阅 管理博客 写新文章
未携带Cookie:目录视图 摘要视图 订阅

我们可以看到携带Cookie后,访问个人主页菜单栏包括了管理博客和写新文章,未携带Cookie则不包括,说明模拟登陆成功。

未登录
未登录

登录成功
登录成功

后记:这里使用的是最简单的模拟登录案例了,稍复杂点的还有带验证码的,登录信息中跳转N次验证的,还有微信网页版那样的扫码验证的,骚年们,任重而道远,继续努力吧。

接下来这个专题写什么呢?

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-10-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
访问管理
访问管理(Cloud Access Management,CAM)可以帮助您安全、便捷地管理对腾讯云服务和资源的访问。您可以使用CAM创建子用户、用户组和角色,并通过策略控制其访问范围。CAM支持用户和角色SSO能力,您可以根据具体管理场景针对性设置企业内用户和腾讯云的互通能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档