今日校園自動提交問卷-Java實現


站在巨人的肩膀上,我所寫的東西,也會開源分享出來!已經能正常用了,但是還需優化一些小bug。

授人以魚不如授人以漁,我把思路分享出來。

如果程序優化好了,我會將源碼放在這里今日校園實現自動檢測並提交最新表單

也可以直接訪問我博客

一、抓包(重點)

1.1 如何抓包

Fiddler4電腦端與手機端抓包的教程,我不多bb了。點這個鏈接里面有具體步驟,這個大佬是專門學習機器學習的,他的博客放到這里

一開始,我是用的Fiddler4來進行抓包的,但是涉及到ssl-pinning的問題。導致抓包失敗,也就是抓取過程中,一堆灰色鏈接。同時,手機上的網路也會被斷開。

之后,我就開始考慮,要不用手機抓包,就下載了HttpCannary,HttpCanary有普通版和高級版之分,建議下載高級版,同樣會遇到ssl-pinning的問題,具體解決方法請移步到系統證書的安裝,解決APP抓不到包,下載軟件點這里

1.2 我的解決方法

此節是廢話,請略過。

我一開始用LuckyPatcher,很幸運的是,雖然顯示破解授權失敗,但打開的時候,發現能用了。

下一步,就是安裝系統證書了,我就把手機root了,我的手機是小米的,直接root就行。

但是,還是在安裝系統證書的過程中出了問題,不能往系統里面移動證書,原因是沒有權限。

后來百度了一下,發現,MIUI的root權限,從Android7之后,就沒有完整的root權限了。除非刷第三方系統。

但是我又舍不得自己的MIUI12。

接下來,就准備用模擬器了,我下載的是逍遙安卓模擬器。安卓的是4.4版本系統,刷入了xposed框架,安裝了justtrustme模塊

然后,打開Fiddler抓包,Yes!

有了Cpdaily-Extension跟MOD_AUTH_CAS這兩條數據,就能模擬提交了。

抓包問題就此解決。耗費了我一整天的時間

二、Java模擬get跟post請求

這個算是套模板吧,都是這個套路,直接上代碼。不要拿來就用,還是根據實際情況進行修改的。

/**
 * HttpUtil類
 * @author kit chen
 * @description 用來模擬發送post請求
 */
public class HttpUtil {
	public static String sendPost(String url, String param,Map<String,String> headers) {
		BufferedWriter out = null;
		BufferedReader in = null;
		String result = "";
		try {
			URL realUrl = new URL(url);
			URLConnection conn = realUrl.openConnection();
			Set<Entry<String, String>> set=headers.entrySet();
			for(Entry<String,String> header:set) {
				conn.setRequestProperty(header.getKey(), header.getValue());
			}
			conn.setDoOutput(true);
			conn.setDoInput(true);
			out = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), "utf-8"));
			out.write(param);
			out.flush();
			in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
			String line;
			while ((line = in.readLine()) != null) {
				result += line;
			}
		} catch (Exception e) {
			System.out.println("發送 POST 請求出現異常!" + e);
			e.printStackTrace();
		} finally {
			try {
				if (out != null) {
					out.close();
				}
				if (in != null) {
					in.close();
				}
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
		return result;
	}
}

三、模擬請求中的問題

通過抓包獲取了請求頭跟請求參數,請求參數還好說。

在抓取請求頭的時候,遇到了點問題。

通過測試發現,如果想要成功提交內容,需要Cpdaily-Extension跟MOD_AUTH_CAS。

如果設備不去主動退出的話,Cpdaily-Extension是會一直存在有效的。類似的像QQ也是這樣的。我在抓取Cpdaily-Extension的過程中,嘗試訪問各種頁面,但是都沒法獲取到這個的值。哪怕是在登錄的時候,也沒有這個參數。只有在提交的時候,才能抓取到。

像MOD_AUTH_CAS這個的值,類似於session,是有有效期的。我目前還沒有測試一直讓這個東西保持有效。這個值,大概6個小時左右,就會失效了,需要重新登錄網頁獲取。

問了大佬,好像是涉及到了cas單點登錄的知識,這塊我也不懂。學!

四、監測表單並返回表單號

今日校園有個獲取今日最新表單的接口,如果沒有的話,里面某個數據會是個空數組。

接口/wec-counselor-collector-apps/stu/collector/queryCollectorProcessingList

post的請求參數{"pageSize": 6,"pageNumber": 1}

這個pageSize是指返回幾條數據,響應請求中,我記得返回的json字符串,最多就只有6個參數,所以這個傳個6就行了。大於等於6

返回的內容

{
	"code": "0",
	"message": "SUCCESS",
	"datas": {
		"totalSize": 0,
		"pageSize": 6,
		"pageNumber": 1,
		"rows": [
            "wid":"xx",
            "formWid":"xx",
            "isHandled":"0"
            ...
        ]
	}
}

我們要的就是這個wid、formWid跟isHandled。isHandled表示是否提交,非0為提交。

監測到有rows有數據,並且isHandled未提交的時候,我們就可以進行模擬提交了。

五、獲取學校表單號

這個還有一個坑就是,每天的學校的表單號schoolTaskWid不是固定的,由此,我們就需要來模擬請求來獲取schoolTaskWid

接口/wec-counselor-collector-apps/stu/collector/detailCollector

post請求參數 {"collectorWid": 傳進來第三步獲取的collectWid}

注意:

這sb接口開發者,一開始定義的是collectWid,結果后面又成了collectorWid,一開始在這邊把我給坑了,需要注意。

這個接口獲取的是collectorWid,第三步獲取的是collectWid,其實他倆是一個東西。

大致的返回內容

{
	"code": "0",
	"message": "SUCCESS",
	"datas": {
		"collector": {
			"wid": "8888",
			"formWid": "164",
			"priority": "5",
			"endTime": "8888-88-88 88:00:00",
			"currentTime": "8888-88-88 88:00:00",
			"schoolTaskWid": "8888",
			"isConfirmed": 1,
			"senderUserName": "牛逼學院(牛逼老師)",
			"createTime": "8888-88-88 88:00:00",
			"attachmentUrls": null,
			"attachmentNames": null,
			"attachmentSizes": null,
			"isUserSubmit": 1,
			"fetchStuLocation": true,
			"address": "xx省xx市xx縣" 
            //這個根據地圖上面的為准,大致就是省市縣
		},
		"form": {
			"wid": "164",
			"formTitle": "8月8日學生身體健康狀況調查",
			"formContent": "https://wecres.cpdaily.com/counselor/1076158768111098/content/d1c0daf5604af56fbccfadaf28cdbd82.html",
			"backReason": null,
			"isBack": 0,
			"attachments": []
		}
	}
}

這里我們需要獲取schoolTaskWid。

六、獲取詳細表單

今日校園還有一條驗證就是每次請求的表的id,以及表選項的id都是變化的。

所有,我們還需要抓取表的詳細表單。

接口/wec-counselor-collector-apps/stu/collector/getFormFields

參數{"pageSize":30,"pageNumber":1,"formWid":formWid,"collectorWid":collectorWid}

返回的內容,依你們老師的設定為准,不放結果了。

七、模擬Post請求提交

7.1 思路

通過上面,我們獲取到了formWid,collectWid,schoolTaskWid,address,form。

接下來,我們構造出post的json字符串請求體。

發送!

成功!

7.2 擴展-郵件通知

如果提交成功,或者提交失敗。都會發通知郵件給我。

但是,試了幾次,經常報錯554 DT:SPM,也就是被當做垃圾郵件駁回了。

嘗試了好幾個郵箱,像139,163,qq郵箱,都會有這個問題,網上說設置端口啊,不要25,要465...開啟ssl...等等

如果涉及到敏感詞,什么簽到、自動,仍然沒有一個奏效的,都沒當成垃圾郵件處理。

剛好看到一個大佬寫的博客,建議用騰訊企業郵箱,試了一下,果然ok了。

記錄一次Could not connect to SMTP host: smtp.163.com, port: 25的解決辦法

騰訊雲或者阿里雲,是默認禁用25端口的

我附上發郵件的代碼

public class SendMail {
	public static String send(String[] mail) {
		Properties properties = new Properties();
        properties.put("mail.transport.protocol", "smtp");// 連接協議
        properties.put("mail.smtp.host", "smtp.exmail.qq.com");// 主機名
        properties.put("mail.smtp.port", "587");// 端口號
        properties.put("mail.smtp.auth", "true");//設置smtp是否需要認證
        properties.put("mail.smtp.ssl.enable", "true");// 設置是否使用ssl安全連接 ---一般都使用
        properties.put("mail.debug", "false");// 設置是否顯示debug信息 true 會在控制台顯示相關信息
        try{
            Session session = Session.getInstance(properties);
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress("xxxxxxxxx@xxxxx.onexmail.com"));
            message.setRecipient(Message.RecipientType.TO, new InternetAddress("meethigher@qq.com"));
            message.setSubject(mail[0]);
            message.setText(mail[1]);
            message.setSentDate(new Date());
            Transport transport = session.getTransport();
            transport.connect("xxxxxxxxx@xxxxxx.onexmail.com", "xxxxxx");//登錄發信賬號
            transport.sendMessage(message, message.getAllRecipients());
            transport.close();
            return "郵件發送成功";
        }catch (Exception e){
            return "郵件發送失敗";
        }
	}
}

7.3 運行結果

去我博客看吧

八、總結

8.1 感謝大佬

python版今日校園自動簽到、填表

python版今日校園自動填報腳本

java定時刷新網頁

手機抓包教程第四節——系統證書的安裝,解決APP抓不到包

記錄一次Could not connect to SMTP host: smtp.163.com, port: 25的解決辦法

java抓取網頁指定元素/內容

模擬登陸系列

QQ空間模擬登錄

還是那句話,站在巨人的肩膀上

8.2 個人收獲

連着兩天,早上5點就起。

因為這個是學校的老師發的表單,我沒有老師權限,沒法模擬。

所以,只能,每天早起,在表單未提交之前,進行測試。這也是最難受的一點。

今天專業課考試,我當時寫代碼寫得正在興頭上,結果作業沒給交上去。估計這學期也就考個60分吧。無所謂了,反正我也不是學霸,計較個錘子。而且,我這學期,也都沒咋聽課,天天在家里就知道玩。每次都下定決心好好學習,結果,嘿嘿...

總得來說,抓包還是很關鍵的。

這個博客算是整理整個的思路,如果思路看明白了,那么,實現這樣的功能就不難了。

我看網上也有不少的類似程序,但是大多數是Python開發的,確實,Python在處理數據的時候,很舒服,給我的感覺,就是跟JavaScript一樣,就是舒服。PHP如果實現這個功能的話,也會比較輕松。

由於我現在正在學java,還沒學透,正好可以拿這個練練手。畢竟,java就像是我的初戀,雖然她身材很臃腫,但我依然愛她啊!

處理過程中,真的感覺人生苦短,多用python

像這樣的功能,好多編程語言都能實現,Java不是不能,只是太繁瑣了。

如果我再次寫這個的話,首選Python,其次Nodejs。

在分層方面,還是覺得自己做地不太好,像學過的繼承多態,我在處理的過程中,就是一直在硬寫、悶頭寫。自己的代碼也能看得出毛病來,但是想優化,卻又不知從何改起。一方面,是對學過的東西,沒有徹底理解;另一方面,也是自己的項目經驗太少了。

一定要花時間,彌補這方面的不足!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM