1. 程式人生 > >用爬蟲模擬登陸urp教務處系統

用爬蟲模擬登陸urp教務處系統

本文轉自本人簡書內容詳情

前言

前段時間,小編抓取了搜狐新聞網某網頁的內容,並作詞雲分析,感覺很是爬蟲有趣。最近突然心血來潮想要爬取一下我們學校的教務系統抓取課表。

思路解析

A 、先開啟登陸頁面,獲取cookies;B、再訪問驗證碼的地址,因為驗證碼是動態的,每次開啟都是不同的,所以我們需要儲存之前的cookie,保證獲取的驗證碼和後續要提交的表單是同步的。C、然後就是識別驗證碼的環節,登陸成功後為了避免網頁的重定向,所以還需要用requests的session函式禁止重定向。D、構建post表單請求資料,然後將資料提交給網站 F、獲取響應頭資訊,通過返回的網頁內容來判斷是否登陸成功。

模擬登陸

在開題之前,先帶大家認識一下:瀏覽器請求網頁的流程。 在web應用中,伺服器把網頁傳給瀏覽器,實際上就是把網頁的HTML傳送給瀏覽器。但是在沒有攜帶cookie的情況下,如果IP短時間高併發的請求網站,該IP就會被封。這裡解釋一下cookie,cookie是一種回話機制,可以用來儲存很多資訊,也經常用於反爬。我們一般處理cookie有兩種方法:1、cookie的儲存 2、cookie的讀取。然後登陸部分的處理通常採用的方法就是將爬蟲模擬成瀏覽器,有:1、通過opener新增headers 2、通過requests新增headers 3、批量新增headers 。小編採用的是第二種方法。 用瀏覽器開啟教務處系統的介面如下: login

上面提到的headers,cookie等引數的獲取,也是有兩種方法獲取。1、在登陸頁面按F12進入開發者模式,選擇network,再選中preserve log,選中login頁面 ,如圖操作: 這裡寫圖片描述 給大家解釋下上圖的主要資訊,在偽裝瀏覽器部分中,重點是獲取請求的頭部資訊和伺服器返回的響應頭(response headers)。 1 request url :是瀏覽器真實請求的地址 2 accept :告訴瀏覽器自己接受什麼型別 3 accept language :瀏覽器所希望的語言種類,當伺服器能夠提供一種以上的語言版本時要用到 4connection 表示是否是持久連線。 5 host 初始url中的主機埠 6 user-agent :瀏覽器型別 關於提交表單的獲取,我們可以嘗試故意輸錯賬號或者密碼得到提交的表單資訊,即通過進入開發者工具或者Fiddler 抓包,如下圖: post
第二種方法就是通過fiddler抓包分析(簡單粗暴)個人比較喜歡。 話不多說,給大家上程式碼:

import requests
import http.cookiejar
from PIL import Image
from bs4 import BeautifulSoup
#導包
cookies = {} #構建一個空字典用來存放cookies
#偽裝成瀏覽器進行網頁請求
headers = {
    'Connection': 'Keep-Alive',
    'Accept-Language': 'zh-CN,zh;q=0.8',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0',
   'Accept-Encoding': 'gzip, deflate',
   'Upgrade-Insecure-Requests':'1',
    'Referer': 'http://172******8******',
    'X-Requested-With': 'XMLHttpRequest',
    'Host': '172.*********',
}

#
#
#構建提交表單
def login(username, password, code):
    url = 'http://172.************/loginAction.do'
    form = {
        'zjh1': '',
        'tips': '',
        'lx': '',
        'evalue': '',
        'eflag': '',
        'fs': '',
        'dzslh': '',
        'zjh': username,
        'mm': password,
        'v_yzm': code
    }
    resp = requests.post(url, headers=headers, data=form, cookies=cookies)

寫到這裡,實在是忍不住要吐槽urp教務系統,程式碼寫得像**一樣,小編在看原始碼時就看懂一個引數“mm”=密碼,其他的引數,,,,,

驗證碼的識別

一般來講,驗證碼的識別有三種方法: 1 人工識別 2 呼叫tesseract-ocr,自動識別 3 接入付費介面進行識別 這裡小編採用的是人工識別,我嘗試了tesseract的pillow庫來識別,額,,,,,效果嘛,因為是免費的,所以識別的成功率一言難盡啊。給大家看下我們教務系統的驗證碼:

check code

沒有經過任何的噪聲處理,成功率僅為百分之25.真的是 # 很無語 #。 思路就是將驗證碼儲存到本地,然後再呼叫PIL的image庫,把驗證碼呈現出來,手動輸入,完成表單的提交。其實我更想爬取所有的驗證碼,然後利用神經網路和機器學習做一個訓練集,進行自動識別。

imgurl = '驗證碼圖片的請求連結'
mysession = requests.Session()
html = mysession.get(imgurl,timeout=60*4)
checkcode = mysession.get(imgurl,timeout=60*4)
with open('checkcode.png','wb') as f:
    f.write(checkcode.content)
check_img = Image.open("checkcode.png")
check_img.show()
v_yzm = input("code:")

然後我們就可以檢驗是否是登陸成功了,小編選取的是課表的查詢:

def get_classinfo():
    url = 'http://172.20.139.153/xkAction.do?actionType=6'
    resp = requests.get(url, headers=headers, cookies=cookies)
    soup = BeautifulSoup(resp.text,'lxml') 
    class = soup.find_all("td")
    print(class)

爬取結果如圖: (ps:這是沒有經過字串處理的,後續小編會系統化輸出結果以及完善成績查詢和選課內容)

result 本人還是個小白,希望大家多多指教。