爬蟲實戰(1)--爬取學校官網獲取成績

前言

前段時間參加軟件杯比賽,第一次真正意義上接觸python,想着暑假無事系統學習下python的有關知識。本着實踐爲主的我,想一邊學習爬蟲,一邊學習知識,這樣印象會更加深刻,於是學校官網成爲我的目標,(每年查成績,那叫一個痛苦,學校的土豆服務器)話不多數,介紹下實現的過程

使用工具以及第三方庫

使用語言:python3.6
開發工具:PyChram
第三方庫:

  1. requests (強大的爬蟲庫)
  2. BeautifulSoup (用於處理爬取的網頁信息)
  3. PIL (圖象處理,本項目用於顯示驗證碼圖片)
  4. 下載方法
    pip install ***

登陸頁面模擬

首先,打開登陸首頁,如果你的學校用的也是正方系統的話,界面如下
在這裏插入圖片描述

獲取登錄時的post參數

爲了看清楚請求登陸時請求的頁面以及請求的的參數,我們點擊F12,查看調試頁面

選擇network ,然後在頁面上嘗試登陸一次,可以發現

登陸請求的頁面是 default2.aspx

我們點擊它,查看他的 form data 也就是發送的請求參數,發現如下:

__VIEWSTATE: 
TextBox1: (我們學校爲學號)
TextBox2: (我們學校爲密碼)
TextBox3: 8cx7(測試發現爲固定值)
RadioButtonList1: %D1%A7%C9%FA(測試發現爲固定值)
Button1: (值爲空,但是發送請求的時候需要發送)

我們發現,對default2.aspx進行post請求的同時,發送了上面幾個參數,其中只有 __VIEWSTATE 的值不確定,所以我們進一步分析發現,在登陸頁面有這樣一個h5語句:

<input type="hidden" name="__VIEWSTATE" value="dDw3OTkxMjIwNTU7Oz5vJ/yYUi9dD4fEnRUKesDFl8hEKA==" />

所以初步判定,__VIEWSTATE的值只需要獲取登陸頁面值就夠了,至此,代碼如下:

import requests
from bs4 import BeautifulSoup

# 學校官網地址
url = ''
# 創建requests
s = requests.session()
# 獲取登錄界面
login_page = s.get(url+'default2.aspx')
# 獲取value值
soup = BeautifulSoup(login_page.text, 'lxml')
__VIEWSTATE = soup.find('input', attrs={'name': '__VIEWSTATE'}).get('value')

以上代碼是在登陸頁面上,抓取頁面的html,然後通過bs4獲取input的value的值,也就是參數中的 __VIEWSTATE

驗證碼處理

之前百度過,正方系統在以前是可以繞過驗證碼的,但是現在似乎被封了。不過遇到問題應該先嚐試着是解決他不去繞過他,這裏的驗證碼提供兩個思路:

第一個:獲取頁面cookies,爬取驗證碼圖片,下載到本地,通過顯示他讓用戶輸入來驗證
第二個:通過機器學習,這裏的驗證碼的背景比較乾淨,訓練起來應該難度不大,推薦crnn

本次我們採用的是第一個辦法,代碼如下:

import requests
from bs4 import BeautifulSoup

# 學校官網地址
url = ''
# 創建requests
s = requests.session()
# 獲取登錄界面
login_page = s.get(url+'default2.aspx')
# 獲取cookie
cookies = login_page.cookies
# 獲取驗證碼
pic = s.get(url+'CheckCode.aspx', cookies=cookies).content
with open('ver_pic.png', 'wb') as f:
    f.write(pic)
# 讀取驗證碼顯示出來
image = Image.open("ver_pic.png")
image.show()    # 顯示
checkcode = input("請輸入驗證碼:")

這裏注意,獲取的驗證碼驗證錯誤大概率是cookies沒處理好,多檢查下。

至此,我們處理好了登陸,以下爲登陸過程的完整代碼:

import requests
from bs4 import BeautifulSoup
from PIL import Image

# 學校官網地址
url = ''
# 創建requests
s = requests.session()
# 獲取登錄界面
login_page = s.get(url+'default2.aspx')
# 獲取cookie
cookies = login_page.cookies
soup = BeautifulSoup(login_page.text, 'lxml')
__VIEWSTATE = soup.find('input', attrs={'name': '__VIEWSTATE'}).get('value')
# 獲取驗證碼
pic = s.get(url+'CheckCode.aspx', cookies=cookies).content
with open('ver_pic.png', 'wb') as f:
    f.write(pic)
# 讀取驗證碼顯示出來
image = Image.open("ver_pic.png")
image.show()    # 顯示
checkcode = input("請輸入驗證碼:")
your_id = input("請輸入學號:")
your_password = input("請輸入密碼:")
# 向登陸頁面發送請求
data = {'__VIEWSTATE': __VIEWSTATE,
        'TextBox1': your_id,
        'TextBox2': your_password,
        'TextBox3': checkcode,
        'RadioButtonList1': r'%D1%A7%C9%FA',
        'Button1': ''}
r = s.post(url+'default2.aspx', data, cookies)

成績爬取分析

這部分的思路與登陸部分相同,並且沒有驗證碼相對比較簡單,就簡單的貼下代碼,提一下注意的幾點內容:

第一:如果爬取內容提示 Object moved to here 需要加請求頭,告訴服務器你是從哪個網址過來的.
第二:__VIEWSTATE 的值其實可以直接寫固定,經過嘗試,固定寫死是可以通過的.

代碼如下:

# 設置響應頭
mark_head = {
    'Referer': url+'xs_main.aspx?xh='+your_id
}
# 設置發送值
find_data = {
    '__VIEWSTATE': '',
    'ddlXN': '',
    'ddlXQ': '',
    'Button2': '%D4%DA%D0%A3%D1%A7%CF%B0%B3%C9%BC%A8%B2%E9%D1%AF'
}

my_cj = s.post(url+'xscj_gc.aspx?xh='+your_id+'&xm='+your_name+'&gnmkdm=N121605', find_data, headers=mark_head)
# 規範化輸出
soup3 = BeautifulSoup(my_cj.text, 'lxml')
marktable = str(soup3.find_all(id="Datagrid1"))
soup2 = BeautifulSoup(marktable, 'lxml')
lines = soup2.find_all('tr')
my_chengji = {}
for tr in lines:
    chengji = []
    soup1 = BeautifulSoup(str(tr), 'lxml').get_text('\t')
    print(soup1)

以上就是全部代碼,有什麼地方不懂的可以提問我哦,相對來說,這個網站的爬取還是蠻簡單的。

最後祝大家敲碼愉快~

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