本章主要講述如何經過花式手段(代理請求)登陸本身學校的正方教務系統,若是看到這篇文章的你學校也是正方教務系統,也是能夠嘗試的。前端
前端:小程序
後端:node
java
1.學校使用的是正方教務系統。node
2.本例子只是提供基礎結構和大體流程,具體的學校系統間的鑑權邏輯須要本身處理一下,通常是cookie,refer等條件須要着重注意一下。python
ping xx.xxxx.cn
注:須要去掉http://或者https://cheerio
,superagent
,charset
)// 大體步驟以下
npm init // 建立項目
npm i cheerio
npm i superagent
npm i charset
複製代碼
我先來總結一下流程:進入教務系統=>找到須要的參數=>找到請求接口=>注意觀察信息=>得到結果npm
用戶名
、
密碼
、
驗證碼
、
身份
],
身份
是默認值,前期能夠選擇先不傳,因此最後要傳的就是[
用戶名
、
密碼
、
驗證碼
]
驗證碼的問題json
用戶名和密碼咱們能夠經過input標籤輸入,可是驗證碼咱們應該如何拿到呢,F12打開控制檯,從標籤中找到驗證碼,驗證碼的url是.aspx
結尾。 此時就不能按常規圖片連接方式處理了,咱們能夠這樣理解,首先這個驗證碼確定是一個動態地址。那麼咱們如何得到這個動態地址,咱們有教務系統的連接,xxx.xxx.xxx/(xxxxxxx)/default.aspx
,作一種假設,我把驗證碼上的xx.aspx
放在連接的後面,是否是就能夠了? 嘗試一下,發現ok。這樣就能夠把連接和xx.aspx
作一個替換放在img的url上。這樣就能夠獲取到驗證碼。如今咱們先不輸入點一下登陸,看看會不會有隱藏信息。 小程序
果真很多,那麼接下來經過常規方式進入教務系統,看看都有哪些被填寫了。 通過測試發現[__VIEWSTATE,txtUserName,TextBox2,txtSecretCode,RadioButtonList1]這幾項是必填的,後四項其實就是表單裏的數據,那麼這個__VIEWSTATE
是哪裏來的,經過標籤搜索我發現它是一個標籤裏的value值。 後端
這一塊其實主要就是界面和接口的實現了,因爲以前的分析咱們已經有了一個大致的思路。 實現思路: onLoad(根據教務系統ip得到url地址) => 輸入用戶信息和驗證碼 => 請求學校的登陸接口緩存
const hostUrl = '學校教務系統IP';
const getCodeUrl = ctx => {
return new Promise((resolve, reject) => {
superagent
.get(hostUrl)
.charset('gb2312')
.set(headers)
.end(function(err, res) {
console.log('res', res);
const body = res.text;
// 得到重定向地址
const systemUrl = res.redirects[0];
// 得到codeUrl後綴
$ = cheerio.load(body);
const viewState = $('#form1 > input')[0].attribs.value;
// 替換返回驗證碼地址
const codeUrl = systemUrl.replace(/default2.aspx/, 'CheckCode.aspx');
resolve({ codeUrl, viewState, systemUrl });
});
});
};
複製代碼
這塊的邏輯就是根據superagent(請求代理模塊)去請求【教務系統】的頁面數據,經過返回的ip進行驗證碼的url地址拼接(保證url的正確性),最後把一些必要的信息返回給前端【小程序】。bash
getCodeUrl: function() {
let that = this;
wx.request({
url: 'http://127.0.0.1:3000/login/getCodeUrl',
header: {
'content-type': 'application/json'
},
success(res) {
const data = res.data;
that.setData({
codeUrl: data.codeUrl,
systemUrl: data.systemUrl,
})
}
})
},
複製代碼
小程序去請求getCodeUrl
得到【驗證碼url】和【教務系統url】。
<!-- login.wxml -->
<view class="container" bindsubmit="formSubmit">
<view class="loginTitle">
<image src="{{loginIcon}}"></image>
<text>登陸</text>
</view>
<form class="loginFrom" bindsubmit="formSubmit">
<view class="formItem">
<text class="title">學號</text>
<input name="txtUserName" placeholder="請輸入學號" maxlength='10' />
</view>
<view class="formItem">
<view class="title">密碼</view>
<input name="TextBox2" placeholder="請輸入密碼" type="password" />
</view>
<view class="formItem">
<view class="title">驗證碼</view>
<input name="txtSecretCode" placeholder="請輸入驗證碼" class="codeInput" maxlength='4'/>
<image src="{{codeUrl}}" class="codeImg"></image>
</view>
<button form-type="submit">提交</button>
</form>
</view>
複製代碼
這塊其實就是普通的頁面展現(大概樣子),主要是爲了讓你能看到在第二步【setData】時的數據是幹什麼用的。完成這三步就完成了【登陸】須要的百分之50功能。
// 表單提交
formSubmit(e){
const data = e.detail.value;
// 登陸主頁
const payload = {
RadioButtonList1:"%D1%A7%C9%FA",
...data
}
this.loginSystem(payload);
},
// 獲得系統主頁連接
getSystemUrl(payload) {
let that = this;
const data = {
__VIEWSTATE: "學校與學校的不同",
Textbox1: "",
Button1: "",
lbLanguage: "",
hidPdrs: "",
hidsc: "",
systemUrl: that.data.systemUrl,
...payload
};
wx.request({
url: 'http://127.0.0.1:3000/login/loginSystem',
method: 'post',
header: {'content-type': 'application/x-www-form-urlencoded'},
data,
success(res) {
const { data:{ errCode = "", url = "", name = "" } = {} } = res;
// 緩存系統地址
wx.setStorageSync('systemUrl',url);
wx.setStorageSync('stuName', name);
wx.setStorageSync('stuCode', payload.txtUserName);
},
complete() {}
})
},
複製代碼
爲了保證看起來比較簡單,我刪去了【加載】【防多點】【異常兼容】等代碼。這塊主要經過form表單得到輸入的數據,通過添加處理後提交給node接收參數。
// 獲取系統主頁面
const getMainSystemUrl = payload => {
// 傳參
const url = payload.systemUrl;
const __VIEWSTATE = payload.__VIEWSTATE;
const data = {
__VIEWSTATE,
txtUserName: payload.txtUserName,
Textbox1: '',
TextBox2: payload.TextBox2,
txtSecretCode: payload.txtSecretCode,
RadioButtonList1: '%D1%A7%C9%FA',
Button1: '',
lbLanguage: '',
hidPdrs: '',
hidsc: ''
};
return new Promise((resolve, reject) => {
superagent
.post(url)
.charset('gb2312')
.set(headers)
.send(data)
.end(function(err, res) {
const mainSystemUrl = res.redirects[0];
const body = res.text;
$ = cheerio.load(body);
const stuName = $('#xhxm')
.text()
.replace(/同窗/, '');
resolve({ url: mainSystemUrl, name: stuName });
});
});
};
複製代碼
這一塊就是node接收到小程序傳遞的參數,對數據進行處理後,去請求【教務系統】的登陸接口,經過接口返回的內容,取出【姓名】【學號】等信息,輔助咱們完成接下來的功能。
若是你看到了這裏,而且每一塊都詳細的看明白了,那你用python,java均可以實現這樣一套簡單的接口請求。可是若是你看完以後,copy到了本身的項目中發現無法使用,你能夠掃描下面的公衆號二維碼,後臺提出問題我替你解答。得到完整源碼能夠微信搜索【前端小白的成長記錄】關注或者掃碼二維碼回覆教務系統
得到。 【注】若是大家學校的教務系統是正方的,源碼
只需修改教務系統IP便可使用,目前已有查詢成績和查詢課表功能。