PHP--用curl完成問卷星答卷

文章目錄

原因

由於公司訂餐系統選用的問卷星系統,有時候工作忙忘記訂餐導致沒飯喫,終於下定決心研究一下怎麼能更方便的喫飯,於是開始研究怎麼用curl來自動化處理問卷星答卷。

實現

首先我們需要了解問卷星頁面。
打開一個問卷星頁面。
這裏是我的一個測試頁面。(https://www.wjx.cn/jq/80375841.aspx)
嘗試提交。
發現當點擊提交的時候會向此地址發送數據。
在這裏插入圖片描述
發送的數據格式如下:
在這裏插入圖片描述

submittype: 1
curID: 80375841
t: 1591198942624
starttime: 2020/6/3 23:42:14
ktimes: 38
rn: 1878089202
hlv: 1
jqnonce: e38ac63f-83c4-433c-8b61-3e1c41b467ae
jqsign: m;0ik>;n%0;k<%<;;k%0j>9%;m9k<9j<>?im

form中包含用戶輸入的答案

submitdata: 1$3}2$test

這裏form比較好理解,表示的第一個空選擇的是第三個選項,第二個空填寫的是test

主要是param攜帶的東西。
根據多次的實驗。
submittype,hlv是不變的
curID表示當前的頁面ID,就是問卷星後面跟的數字。

那麼接下來要解開其餘ID的迷。

t: 1591198942624  //表示當前時間戳 毫秒 這裏表示的是提交時間!!
starttime: 2020/6/3 23:42:14 //當前打開頁面時間
ktimes: 38  //答題時間,猜測
rn: 1878089202  //目前暫且不知
jqnonce: e38ac63f-83c4-433c-8b61-3e1c41b467ae //不知
jqsign: m;0ik>;n%0;k<%<;;k%0j>9%;m9k<9j<>?im  //不知,但是是一個簽名認證

這時候迷惑的主要是幾個很奇怪的ID。
rn,jqnonce,jqsign,ktimes的獲取。只要搞到這幾個ID怎麼來的就可以了。
我們抓一下答題頁面。

在這裏插入圖片描述
在這裏插入圖片描述

此時,就剩rn和ktimes,jqsign不知道怎麼來的。
我們看到其中有一個rndnum和rn一樣,那麼基本可以確定。rn,jqnonce,starttime都可以獲取頁面中原有的。

那麼jqsign到底怎麼來的呢。
我們看一下頁面點擊事件觸發的js。
在這裏插入圖片描述
看代碼,在代碼中搜索jqsign

window.jqnonce &&
(e += "&jqnonce=" + encodeURIComponent(window.jqnonce), 
k = dataenc(window.jqnonce), 
e += "&jqsign=" + encodeURIComponent(k)), 

jqsign是調用了dataenc方法根據jqnonce計算出來的。

function dataenc(a) {
    var c, d, e, b = ktimes % 10;
    for (0 == b && (b = 1), c = [], d = 0; d < a.length; d++) e = a.charCodeAt(d) ^ b,
    c.push(String.fromCharCode(e));
    return c.join("")
}

這段代碼獲取jsqnonce的每一個字符的Unicode碼和b做抑或,最後再把相應的Unicode碼轉換爲對應的字符。
我用PHP重寫了,代碼在下面。

那麼到了這一步,我們把參數中需要獲取的已經獲取完全了。
ktimes也只是取了一個累加的數值,我們給隨機即可。
在這裏插入圖片描述

那麼此時,我們就把需要的數據全部拿到了,下面貼一下用PHP實現的代碼。

//dataenc實現
function dataenc($a,$ktime)
{
    $c = "";
    for ($d = 0;$d < strlen($a);$d++){
        $b = $ktime % 10;
        if ($b == 0) $b = 1;
        //轉換unicode
        $e = ord($a[$d]) ^ $b;
        //unicode轉爲字符
        $c = $c . utf8_encode(chr($e));
    }
    return $c;
}

//獲取毫秒
function getMillisecond() {
    list($t1, $t2) = explode(' ', microtime());
    return (float)sprintf('%.0f', (floatval($t1) + floatval($t2)) * 1000);
}

//獲取問卷星提交url
function getWJXSubmitURL($wjxId)
{
    $microTime = getMillisecond() + mt_rand(100,300);
    $bookHtml = "https://www.wjx.cn/jq/".$wjxId.".aspx";
    $s = request_by_curl($bookHtml, "",$bookHtml);
    //從頁面中獲取starttime,jqnonce,rndnum這三個值
    preg_match_all('/starttime=\"(.*)\"/',$s,$startTimes);
    preg_match_all('/jqnonce=\"(.*)\"/',$s,$jqnonces);
    preg_match_all('/rndnum=\"(.*)\"/',$s,$rndnum);
    $startTime = urlencode($startTimes[1][0]);
    $jqnonce = $jqnonces[1][0];
    $rn = $rndnum[1][0];
    //ktimes隨機即可
    $ktimes = mt_rand(10,50);
    $jqsign = urlencode(dataenc($jqnonce,$ktimes));
    $param = "submittype=5&curID=".$wjxId."&t=".$microTime."&starttime=".$startTime.
        "&ktimes=".$ktimes."&rn=".$rn."&hlv=1&jqnonce=".$jqnonce."&jqsign=".$jqsign."&jpm=21";
    $dinnerURL = "https://www.wjx.cn/joinnew/processjq.ashx?".$param;
    return $dinnerURL;
}

結果

嘗試用此腳本每隔50ms運行一次,總共運行100次,後臺全部接收到響應,數據也正確存入,但是之後再提交就需要驗證了。
如果有需要刷腳本請代理ip。
在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章