java模拟登陆教务系统_【Java】模拟登录教务网并获取数据

本文详述如何使用Java模拟登录教务系统,包括前端加密密码的JS解析、Java运行JS代码以及使用Okhttp进行模拟POST请求。通过分析请求接口和头信息,实现登录并获取数据。
摘要由CSDN通过智能技术生成

本文章仅做技术交流演示学习,请勿用于违法操作!

前期准备

首先我们需要到要模拟登录的网页,进行抓包操作。

使用Chrome浏览器打开系统的登录页面,按F12打开开发者工具

切换到Network选项卡

e93e346fea3778dc5e4bec4f8511d4b0.png

然后正常进行登录操作。

登录成功后,可以在右面看到加载出很多的数据,我们需要逐一查看Headers找到对应的登录接口

如图所示,大部分都是login相关的页面名称。

e49905f146b67a3f600295ec4dfc767c.png

很显然,这个接口URL即我们想要的请求登录接口。

RequestURL:http://打码/jsxsd/xk/LoginToXk

a7205667aaccacc316888ba38646543a.png

根据登录界面和FormData 我们知道,登录提供的是账户和密码,但是浏览器在请求的时候是三个参数,分别为:userAccount,userPassword,encoded

显然userAccount即我们提供的账号,userPassword是密码但为空,encoded是一堆看不懂的密文

初步推测是encoded应该是加密过后的密码

那么加密过程一定是在前端完成的,我们根据经验加密函数应该也是使用js写的。

回到登录界面,开启开发者模式,刷新一下,果然在列表中有一个名为conwork.js的文件

6fb6b67efdefc3fb6411af3de2d6435e.png

该文件就是用来对密码进行加密的文件,我们将其保存下来。

eval(function(p, a, c, k, e, d) {

e= function(c) {return (c < a ? "" : e(parseInt(c / a))) + ((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36))

}

;if (!''.replace(/^/, String)) {while (c--)

d[e(c)]= k[c] ||e(c);

k= [function(e) {returnd[e]

}

];

e= function() {return '\\w+'}

;

c= 1;

}

;while (c--)if(k[c])

p= p.replace(new RegExp('\\b' + e(c) + '\\b','g'), k[c]);returnp;

}('b 9="o+/=";p q(a){b e="";b 8,5,7="";b f,g,c,1="";b i=0;m{8=a.h(i++);5=a.h(i++);7=a.h(i++);f=8>>2;g=((8&3)<<4)|(5>>4);c=((5&s)<<2)|(7>>6);1=7&t;k(j(5)){c=1=l}v k(j(7)){1=l}e=e+9.d(f)+9.d(g)+9.d(c)+9.d(1);8=5=7="";f=g=c=1=""}u(i

到此,前期准备就完成了。

模拟登录

本文使用Java来进行编写,其他语言原理类似。

Java运行JS代码

首先要解决的就是,如何能在java代码中运行这个使用js编写的加密函数。

当然,如果有能力看懂的话,你也可以重写一遍这个方法,可以跳过本段内容。

我们使用的是Java自带的解决方案:ScriptEngineManager

首先编写一个通用方法:

/*** 从给定的js文件中获取指定接口中的方法的实例

*@paramjs js字符串

*@paramclazz 接口的class

*@return返回一个指定接口方法的实例*/

public T getMethod (Classclazz,String js) {

ScriptEngineManager manager= newScriptEngineManager();

ScriptEngine engine= manager.getEngineByName("js");try{//1.可以直接读取指定目录下的文件//String path = ExecuteScript.class.getResource("").getPath();//System.out.println(path);//FileReader的参数为所要执行的js文件的路径//engine.eval(new FileReader(fileLoacation));//2.直接加载字符串

engine.eval(js);if (engine instanceofInvocable) {

Invocable invocable=(Invocable) engine;

T executeMethod=invocable.getInterface(clazz);returnexecuteMethod;

}

}catch(Exception e) {

e.printStackTrace();

}return null;

}

然后根据Js的方法创建一个接口,接口中的方法名称要和js中的方法名称对应。

public interfaceJSMethods {publicString encodeInp(String input);

}

使用方法:

/*** 加密

*@paramonecard 学号

*@parampassword 密码

*@return加密的学号+%%%+加密的密码

**/

privateString getEncodeString(String onecard,String password){

ExecuteScript executeScript= newExecuteScript();//String fileLocation="src/main/resources/templates/conwork.js";//通过下面一行代码就可以获取指定接口中方法的实例

JSMethods method = executeScript.getMethod(JSMethods.class,JscriptMethod.data);

String result=method.encodeInp(onecard);

String pass=method.encodeInp(password);return result+"%%%"+pass;

}

这里的result是根据实际encoded结果分析出来的。

使用Okhttp进行模拟Post请求

首先创建请求体:requestbody

RequestBody requestBody=newFormBody.Builder()

.add("userAccount",account)

.add("userPassword","")

.add("encoded",getEncodeString(account,password))

.build();

必须与我们前面分析出来的请求参数一一对应。

接着我们创建一个request请求:

Request request=newRequest.Builder()

.url(REQUEST_JW_URL)

.header("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8")

.header("User-Agent","Mozilla")

.post(requestBody)

.build();

这里的请求头,可以参考浏览器获取的结果

58fe8802e6b42ba2c739e5be855338cc.png

然后使用okhttpclient发起post请求即可,根据response判断是否登录成功

/*** 模拟登陆

*@paramaccount 学号

*@parampassword 密码

**/

privateString login(String account,String password){

String result="";

RequestBody requestBody=newFormBody.Builder()

.add("userAccount",account)

.add("userPassword","")

.add("encoded",getEncodeString(account,password))

.build();

Request request=newRequest.Builder()

.url(REQUEST_JW_URL)

.header("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8")

.header("User-Agent","Mozilla")

.post(requestBody)

.build();try{

Response response=client.newCall(request).execute();

result=response.body().string();

}catch(IOException e) {

e.printStackTrace();

}returnresult;

}

如果需要登录后进行访问其他页面获取数据,这里只需要配置一下okhttp的cookies管理工具:

public OkHttpClient client = new OkHttpClient.Builder()//这个cookies就不存在本地了,因为不需要验证码直接登录,每次刷新就好

.cookieJar(newCookieJar() {

@Overridepublic void saveFromResponse(HttpUrl httpUrl, Listlist) {

cookieStore.put(httpUrl.host(), list);

}

@Overridepublic ListloadForRequest(HttpUrl httpUrl) {

List cookies =cookieStore.get(httpUrl.host());return cookies != null ? cookies : new ArrayList();

}

})

.build();

全局都使用该client进行请求即可,注意无论是同步还是异步操作都要保证login成功

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值