1. 程式人生 > >教務系統模擬登入與成績爬取一

教務系統模擬登入與成績爬取一

版權宣告:本文為博主原創文章,轉載 請註明出處 https://blog.csdn.net/sc2079/article/details/82563854

-寫在前面


  暑假期間學校的學生教務系統大改,好多以前的微信公共號的爬蟲都不能用了。想快速查成績怎麼辦呢?哎,自己動手豐衣足食,不妨自己寫個爬蟲!
  上次寫個中國大學MOOC課程資訊爬取與資料儲存部落格,使用的是selenium+Chrome。而這次,不妨採用requests傳送post、get請求獲取資料。

-環境配置安裝


  執行環境:Python3.6、Spyder
  依賴的模組:bs4,requests.re,JSON,pymysql等

-開始工作


1. 模擬登入

  關於瀏覽器的選擇,這裡我推薦Firefox(可以看到post資料,並能模擬重發資料)。當然,如果你有fiddle等抓包工具的話,其他瀏覽器也OK。
  開啟登入介面:

  輸入賬號密碼,按F12開啟開發者工具,再點選登入。

  此時在網頁上可以看到自己的一些資訊,比如自己的姓名,登入日期,學業資訊等。此時我們觀察開發者工具的網路視窗。

  其中,第一個就是我們的post登入請求,觀察請求頭(原始頭)和請求引數。

  複製編輯請求頭。

headers2={
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0',   
    'Cookie': 'JSESSIONID=bcdAIJyUvw0e24cRYH8ww;selectionBar=1443374',  
    }

  這裡我去掉了一些對於請求無影響的欄位。
  檢視請求引數。

  複製編輯請求引數

data={
      'j_captcha1':'error',
      'j_password':'××××××',
      'j_username':'×××××××××'
      }

  經測試,登入成功。

url='http://×××××××××/j_spring_security_check'
r=requests.post(url,headers=headers,data=data)

2. 獲取日期和使用者名稱

  網頁上的日期和使用者名稱

  在開發者工具中找到這個資訊。

  注意上面的請求網址變化了,且請求方法為Get。

  使用get請求獲取網頁資訊再用bs4解析分別獲得日期和使用者名稱。

'''獲取登入日期和使用者姓名'''
url2='http://××××××/index.jsp'
r2=requests.get(url2,headers=headers)  
soup=BS(r2.content,'html.parser')  
time=soup.find_all(name='i',attrs={'class':'ace-icon fa fa-calendar'})[1].parent.get_text()
time=re.sub('[\n\r]','',time)   #登入日期
user=soup.find_all(name='span',attrs={'class':'user-info'})[0].get_text()
user=re.sub('[\n\t\r歡迎您\,]','',user)  #使用者姓名

  這裡需要說明的是獲取使用者名稱和日期時需要用re去掉無關字元。

3. 獲取學業資訊

  網頁上的學業資訊見前圖。這裡同樣開啟開發者工具,找到相關資訊。

  注意這裡請求網址又不一樣,且為post請求,這就需要找到請求頭和請求引數。

  請求引數只有一個為空值。

'''獲取學業資訊及本學期課程資訊'''
headers3={
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0',
    'Accept': 'application/json, text/javascript, */*; q=0.01',
    'Referer': 'http://*********/index.jsp',
    'Cookie': 'JSESSIONID=bcdAIJyUvw0e24cRYH8ww;selectionBar=1443374',
    }
data3={
    'flag':''
    }
r3=requests.post(url3,headers=headers3,data=data3)
Academic_info=r3.json()   #讀入返回的JSON資料
passed_course_num=Academic_info[0]['courseNum']    #已修讀課程門數
failed_course_num=Academic_info[0]['coursePas']    #為及格課程門數
gpa=Academic_info[0]['gpa']              #GPA
courseName=Academic_info[0]['courseName']    #本學期課程名
teacherName=Academic_info[0]['teacherName']    #本學期課程教師
jasName=Academic_info[0]['jasName']         #本學期課程上課教室

  這裡需要注意的是請求頭需要增加’Accept’欄位(表示請求的JSON資料),否則會報錯。

4. 獲取所有修讀課程資訊

  在主頁面點選成績查詢中的及格成績,便可以檢視各學期各學科成績。

  同樣,在開發者工具中找到相關資訊:

  開啟第一個課程

便可以找到所需要的資訊。回過頭來看下請求頭。

  參照編寫程式碼。

'''獲取全部成績資訊並儲存JSON檔案'''
url4='http://zhjw.scu.edu.cn/student/integratedQuery/scoreQuery/allPassingScores/callback'
r4=requests.get(url4,headers=headers3)
all_grade_info=r4.json()  #匯入JSON
with open('mygrades.json','w',encoding='utf-8') as f:   #儲存課程成績
    json.dump(all_grade_info,f,ensure_ascii=False)

  至此,課程資訊獲取完畢。

-未完待續


  這裡有些問題需要說明一哈:
  1. 我測試時有時發現請求失敗,其原因是網頁設定了超時時間,Cooikes失效。
  2. 針對上個問題,requests有會話保持的功能。但是我在使用時有問題。

conn = requests.session()

  本篇部落格從網頁上獲取的JSON資料,下篇部落格將為你提供查詢學期成績、查詢某個學科成績等功能。教務系統模擬登入與爬取二