Request之post方法(Data為Request Payload形式)的使用


今晚運用剛學的post請求的知識,爬取了學校系統中的課程表,雖然很easy,但對於我來說還是件很有成就感的事~

 


 

首先這是我們學校的教務系統的全校課程表界面,可以看到,如果要獲取所有的課程表的話,基本就是選取每個學年學期的每個開課單位,並進行查詢,將查詢結果的每一頁內容爬取下來,最終整合到一起,就ok了。其他的選項,如上課周次、星期、課程性質等等,不用選擇,默認就是全部。

 而對於各個學年學期,各個開課單位,以及各個頁碼,則就是一個循環的事兒。下面就着手核心部分。

通過F12在瀏覽器控制台中的分析,很容易發現含有要尋找信息的條目。

 發現請求方式為POST。(由於我以前練習的都是GET請求,所以當我發現不同學院課程表的url竟然都是相同時,才發覺是POST方式233)

 而且是Request Payload 形式的POST請求,而不是Form Data了,但正常處理。(哼,還以為什么呢,第一次見到嚇了本小白一跳,於是學習了這篇文章:python爬蟲如何POST request payload形式的請求

 請求部分代碼如下,其中對payloadData的處理上面的鏈接中給了好幾種方式,都可以。params就是上圖的Query String Parameters,復制即可。不過headers我最初挑了好幾個,卻總是相應無內容,一氣之下(哼!)把request headers全部copy過來,大成功!

payloadData = {"nj":"","zc":"","jcList":[],"jczy003id":"","kkdwid":"100700","jczy013id":"2020-2021-1","jczy004id":"","jczy010id":"","kcname":"","jsname":"","skls_name":"","jczy002id":"","xqList":[],"jczy008id":"","pkgl002id":"c1343bd90000WH","kclbcode":"","sctype":"zgrmdx","sfcxjxdgcode":"1","page":{"pageIndex":3,"pageSize":10,"orderBy":"[{ \"field\": \"kcbh\", \"sortType\": \"asc\"},{ \"field\": \"id\", \"sortType\": \"asc\"}]","conditions":"QZDATASOFTJddJJVIJY29uZGl0aW9uR3JvdXAlMjIlM0ElNUIlN0IlMjJsaW5rJTIyJTNBJTIyYW5kJTIyJTJDJTIyY29uZGl0aW9uJTIyJTNBJTVCJTVEJTdEyTTECTTE"}}
r = requests.post(url, data=json.dumps(payloadData), headers=headers,params=params)
r.json()

下面是返回的結果

{'errorCode': 'success',
 'errorMessage': 'success',
 'errorMessageParam': [],
 'data': {'rowCount': 116,
  'items': [{'xsfl1': ' 36(1-17)',
    'skdx_name': '2019工商管理-法學實驗班1班,2019新聞學-法學實驗班1班,2018新聞學-法學實驗班1班,2019級法學本科一班,2019級法學本科三班,2019級法學本科二班',
    'xsfl2': None,
    'pklb_name': '法學院排課',
    'xsfl3': None,
    'xsfl4': None,
    'bkxt004id': 'c1343d070000Xj',
    'xsfl5': None,
    'tk_name': '',
    'xsfl6': None,
    'jhxs': 36,
    'ktmc_name': '國際法02班',
下面略
}

對此進行處理就ok了。那么怎么切換到不同的學院、不同的學期的課程表呢?這里再看一下request payload的數據,下面是經過格式化顯示了的。可以發現,里面的參數寫的很清楚,只需要根據情況稍稍改動就可以了。

{nj: "", zc: "", jcList: [], jczy003id: "", kkdwid: "100700", jczy013id: "2020-2021-1", jczy004id: "",…}
jcList: []
jczy002id: ""     ###這些空的引號表示沒選,即默認全部
jczy003id: ""
jczy004id: ""
jczy008id: ""
jczy010id: ""
jczy013id: "2020-2021-1"   ###這是時間信息,意為2020-2021學年秋季學期(用1表示),春季學期則用2表示。
jsname: ""
kclbcode: ""
kcname: ""
kkdwid: "100700"  ###即開課單位id,因此只需要獲得所有學院的id,就可以進行for循環了
nj: ""
page: {pageIndex: 2, pageSize: 30,…} 
conditions: "QZDATASOFTJddJJVIJY29uZGl0aW9uR3JvdXAlMjIlM0ElNUIlN0IlMjJsaW5rJTIyJTNBJTIyYW5kJTIyJTJDJTIyY29uZGl0aW9uJTIyJTNBJTVCJTVEJTdEyTTECTTE"
orderBy: "[{ "field": "kcbh", "sortType": "asc"},{ "field": "id", "sortType": "asc"}]"
pageIndex: 2  ###這里是頁碼,下一條是每頁顯示條數(這個沒法改成比如300這樣的大數字,因為在頁面的選項卡里有最大50這個限制)
pageSize: 30
pkgl002id: "c1343bd90000WH" #這些參數發現都是固定不變的,不用管它們
sctype: "zgrmdx"
sfcxjxdgcode: "1"
skls_name: ""
xqList: []
zc: ""

至於開課學院的id信息,可以從另一個url很方便地獲取到(真的很工整呢,愛了!)其實這里包含了所有的id信息,包括學期id。

 這樣就萬事具備了!嗯,連東風都齊全了。不過后面我就沒再寫,有了思路框架,內容則水到渠成,什么時候想寫再說吧哈哈。

 

不過剛才過了一段時間再次查詢,出現了錯誤提示,說Token過期,不過這對爬取全校課程表應該沒什么影響,因為有效期還是很長的,應該有二十分鍾左右,對獲取全部信息來說完全足夠了。

 


 

這篇文章的原理其實非常簡單吶,不過寫得像日記一樣2333,感覺還是很有趣的!

以及一些有關的學習鏈接:

Python學習筆記:requests請求傳遞Query String Parameters參數及提交From Data數據。

python中requests庫的post請求 4種類型參數


免責聲明!

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



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