最近遇到老師用Google表單給了考古題,但是答案要自己找的作業,裡面題目也沒有附題號,所以如果寫完題目後按提交,就不知道自己到底寫了啥不能複習(也不能跟同學對答案
於是,我就想要一個可以快速匯出我在Google表單填的資料的方法,假設表單只有一頁,可能是大量的單選題。
說到這裡,想想大概就是用js,在console印出來是最簡單暴力的,所以第一個被我找到的是jQuery的serializeArray(),這個以前也有人討論過(參考資料)
只要找到form元素的id,jQuery就幫你表單的所有input的value匯整到一個陣列裡了,前提是要自己引入jQuery,於是我就迅速寫了以下js掛到console上:
var s = "";
var formId = "mG61Hd"; //表單元素id
var qNumbers = 50;
var ansArray = $("#"+formId).serializeArray();
for (var i = 0; i < qNumbers ;i++) {
s += (i+1) + ":";
s += ansArray[i]["value"];
s += "\n";
}
console.log(s);
誰知道後來發現只有我能用,同學匯出竟然都是亂序的這樣就對不了答案了,才知道似乎是Google表單在儲存草稿,重新整理後,每個input的name裡面的序號會重新打亂,最後serializeArray()照name排列出來的順序就是亂的,而我是網頁一直開著沒有重整。
好吧,那只好認真花點時間來研究...
後記(雪上加霜):本來引入jQuery我會暴力地找個CDN,把整個js檔內容複製貼到cosole執行,就完成腳本的載入了,後來我寫文章的時候發現Google Form更新過,用了TrustedHTML(簡單來說就是一個白名單讓我沒辦法輕易地載入外來腳本),所以這個方法就真的失效了(除非哪天我知道可以怎麼繞過)
認真看了幾眼前端程式,我找到"FB_PUBLIC_LOAD_DATA_"這個變數,裡面有表單名稱,網址等等,有所有題目和其序號的對照在FB_PUBLIC_LOAD_DATA_[1][1]
裡。
所以邏輯如下:
FB_PUBLIC_LOAD_DATA_[1][1][題號][4][0][0]
得到每題的專屬序號(identifier)FB_PUBLIC_LOAD_DATA_[1][1][題號][1]
),就可以輸出想要的結果了FB_PUBLIC_LOAD_DATA_[1][1]
裡面的順序不會因為表單的隨機決定問題順序設定打亂,匯出的順序每個人每一次還是會一樣初步寫的程式:
var formId = "mG61Hd"; // 表單ID
var form = document.getElementById(formId); // 獲取表單元素
var shuffledAns = form.getElementsByTagName("input"); // 獲取所有input元素
var result = "";
FB_PUBLIC_LOAD_DATA_[1][1].forEach((question, QNumber) => {
var sortedId = question[4][0][0]; // 記錄序號的位置
for (var i = 0; i < shuffledAns.length; i++) {
if (shuffledAns[i].name == "entry." + sortedId) {
result += QNumber + 1 + ":";
result += shuffledAns[i].value;
result += "\n";
}
}
});
console.log(result);
試著用些進階點的語法:
//google表單印出優化版
var formId = "mG61Hd"; // 表單ID
var shuffledAns = document.getElementById(formId).getElementsByTagName("input"); // 獲取表單中所有的input元素
var result = "";
FB_PUBLIC_LOAD_DATA_[1][1].forEach((element, questionNumber) => {
var sortedId = element[4][0][0]; // 記錄序號的位置
Array.prototype.some.call(shuffledAns, (element) => {
var findAns = element.name == "entry." + sortedId;
if (findAns) {
result += questionNumber + 1 + ":";
result += element.value;
result += "\n";
}
return findAns; // 找到答案時返回true,讓some()結束遍歷
});
});
console.log(result);
輸出結果:
可惜下面的參考資料再我寫完後才找到的,也許就能省下點時間,但他分析的更完整,也有介紹非單選題以外的答案怎麼判斷和取得,有興趣的可以參考看看