问题分析

通过HttpClient获取网页数据源,通过Jsoup解析数据。先模拟登录统一身份认证平台,再通过单点登录方式登录正方教务系统,最后获取相关信息。模拟浏览器正常操作,封装请求头信息获取SESSIONID。

解决方案

Maven

        <dependency>
            <groupId>com.baidu.aip</groupId>
            <artifactId>java-sdk</artifactId>
            <version>4.8.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.2</version>
        </dependency>
        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.11.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.4</version>
        </dependency>
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20160810</version>
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.56</version>
        </dependency>

 

登录统一身份认证平台

登录请求表单数据 

密钥与加密密码均为Base64编码

 

常见加密:

1)数据加密标准(DES Data Encryption Standard):DES(密钥长度64位)(ECB模式)

2)分组密码算法:AES(密钥长度在128位及以上)(GCM或CBC模式)

3)流密码算法:AES(密钥长度在128位及以上)(OFB或CTR模式)、chacha20

4)哈希算法:SHA2、SHA3

5)密钥交换算法:DSA/DH(密钥长度2048位及以上)、ECDH(密钥长度223及以上)

6)HMAC(基于哈希的消息验证码)算法:HMAC-SHA2

7)非对称加密算法:RSA(2048位及以上)、ECC(256位以上)

DEC解密 

此统一身份认证平台密码加密采用DES/ECB/PKCS7Padding方式加密。

相关加密解密方法,自行百度。

参考:https://shentuzhigang.blog.csdn.net/article/details/107323907

密钥获取

在登录页面HTML代码中可以找到 

模拟登录

package cn.edu.zstu.myzstu.spyder.sso;

import cn.edu.zstu.myzstu.model.Student;
import cn.edu.zstu.myzstu.utils.DESUtil;
import cn.edu.zstu.myzstu.utils.httpclient.HTTPResponse;
import cn.edu.zstu.myzstu.utils.httpclient.HttpClientUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author ShenTuZhiGang
 * @Version 1.0.0
 * @Date 2020-03-20 18:04
 */
@Component
public class SSOLoginer {
    private final String LOGIN_URL="https://sso.zstu.edu.cn/login";
    public boolean login(String username,String password){
        Document doc = Jsoup.parse(HttpClientUtils.doGetRequest(LOGIN_URL,null,null));
        String currentLoginType = doc.select("#current-login-type").html();
        String loginCroypto = doc.select("#login-croypto").html();
        String ssoSecond = doc.select("#sso-second").html();
        String userId = doc.select("#user-id").html();
        String userObjectId = doc.select("#user-object-id").html();
        String lphoneNumber = doc.select("#phone-number").html();
        String loginRuleType = doc.select("#login-rule-type").html();
        String loginPageFlowKey = doc.select("#login-page-flowkey").html();
        String captchaUrl = doc.select("#captcha-url").html();
        String redirectUri = doc.select("#redirect-uri").html();
        String loginBackUri = doc.select("#login-back-uri").html();
        String loginErrorCode = doc.select("#login-error-code").html();
        String recaptchaInvisible = doc.select("#recaptcha-invisible").html();

        Map<String,String> params=new HashMap<>();
        params.put("username",username);
        params.put("type",currentLoginType);
        params.put("_eventId","submit");
        params.put("geolocation","");
        params.put("execution",loginPageFlowKey);
        params.put("captcha_code","");
        params.put("croypto",loginCroypto);
        params.put("password", DESUtil.encrypt(loginCroypto,password));
        HTTPResponse httpResponse = HttpClientUtils.doPostRequest(LOGIN_URL, null, params);
        System.out.println(loginCroypto);
        System.out.println(DESUtil.encrypt(loginCroypto,password));
        System.out.println(httpResponse);


        return true;
    }
}

注:HttpClient封装工具类,自行百度。

参考:https://shentuzhigang.blog.csdn.net/article/details/104274609

登录正方教务系统

单点登录抓包 

单点登录

package cn.edu.zstu.myzstu.spyder.edu;

import cn.edu.zstu.myzstu.spyder.sso.SSOLoginer;
import cn.edu.zstu.myzstu.utils.httpclient.HttpClientUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author ShenTuZhiGang
 * @Version 1.0.0
 * @Date 2020-07-13 23:36
 */
@Component
public class EduSSOLoginer {
    @Autowired
    private SSOLoginer ssoLoginer=new SSOLoginer();
    public boolean login(String username,String password){
        if(ssoLoginer.login(username,password)){
            String location= HttpClientUtils.doGetRequest("https://sso.1.edu.cn/login?service=http%3A%2F%2Fjw.1.edu.cn%2Fsso%2Fjasiglogin",null,null);
            int i;
            List<String> list = new ArrayList<>();
            for(i=0 ;i<6;i++){
                //如果是重定向,则继续请求。
                if(location.contains("http")&&location.length()<150){
                    list.add(location);
                    location = HttpClientUtils.doGetRequest(location,null,null);
                }else{
                    break;
                }

            }
            System.out.println(i);
            for (String str:list) {
                System.out.println(str);
            }
            return true;
        }
        return false;
    }
}

测试

@Test
    public void Gradetest4() throws Exception {
        System.out.println("Gradetest4");
        EduSpyder eduSpyder = new EduSpyder();
        EduSSOLoginer eduSSOLoginer = new EduSSOLoginer();
        GradeParser gradeParser = new GradeParser();
        List<Grade> data = null;
        try {
            if(eduSSOLoginer.login("username","password")) {
                data = gradeParser.parse(eduSpyder.crawlGrades(new Student()));
            }
        } catch (Exception e) {
            throw e;
        }

        List<Grade> scoreList= data;
        for(Grade score:scoreList){
            System.out.println(score);
        }
        System.out.println(scoreList.size());
    }
    //获取成绩信息页面
    public String crawlGrades(Student stu) {
        Map<String,String>scoreParams=new HashMap<>();
        scoreParams.put("xnm","");
        scoreParams.put("xqm","");
        scoreParams.put("_search","false");
        scoreParams.put("nd",""+new Date().getTime());
        scoreParams.put("queryModel.showCount","100");
        scoreParams.put("queryModel.currentPage","1");
        scoreParams.put("queryModel.sortName","");
        scoreParams.put("queryModel.sortOrder","asc");
        scoreParams.put("time","1");
        try {
            String scoreResponse = HttpClientUtils.doPostRequest(CHECK_GRADE_URL,
                    null,
                    scoreParams).getContent();
            return  scoreResponse;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

 注:成绩页面解析与成绩类等,自行编写。

参考:https://shentuzhigang.blog.csdn.net/article/details/104262854

运行结果

参考文章

https://shentuzhigang.blog.csdn.net/article/details/107323907

https://shentuzhigang.blog.csdn.net/article/details/103996741

https://shentuzhigang.blog.csdn.net/article/details/104262854

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐