Python爬蟲:爬取北京師範大學珠海分校課程表

本篇文章只是記錄一下python課的小作業而已沒啥技術含量。(順便練練Markdown語法?)

需要的庫:

  • requests:請求網站
  • bs4:用於解析HTML文件
  • PIL:圖像處理標準庫,看驗證碼
  • lxml:依舊是一個很好用的解析庫
  • io

實現過程:

模擬登陸:

準備工作

  • 打開教務網站,再打開開發者工具,有一個network選項,登陸後能看你的登錄操作提交了哪些東西,我們就是要來模擬這個。
    登陸之前打開這個
    登陸之後:一般正方的教務系統都是這個文件

    在這裏插入圖片描述
  • __VIEWSTATE和__EVENTVALIDATION每一次打開登錄界面都不同,在模擬登陸之前,我們還得要提前提取這兩個信息。
    ‘TextBox1’: 學號
    ‘TextBox2’:密碼
    ‘TextBox3’:驗證碼

session可以保持連接並多次請求
index就是教務網站的 html

session=requests.session()#能夠幫我們跨請求保持某些參數,也會在同一個session實例發出的所有請求之間保持cookies。
url="http://es.bnuz.edu.cn/"
login_page=session.get(url,headers=headers)

我們先構造這個字典

datas={  
        'TextBox1':'',  
        'TextBox2':'',  
        'TextBox3':'',  
        'RadioButtonList1':u"學生".encode('gb2312','replace'),  
        'Button4_test': '',  
        '__VIEWSTATE':'',  
        '__EVENTVALIDATION':'',  
        '_VIEWSTATEGENERATOR':'',  
        '__PREVIOUSPAGE':''  
    }  

驗證碼:

只有學號和密碼是不能登錄的,我們還要拿到它的驗證碼。
驗證碼圖片可以通過開發者工具裏面找到其src:
http://es.bnuz.edu.cn/CheckCode.aspx
再利用圖片標準庫在python中打開這個圖片

def get_check_code(checkcode,session,headers):
    img = session.get(checkcode, stream=True, headers=headers)
    check_code = int(input("input code:"))
    with open('checkcode.gif', 'wb') as f:
        f.write(img.content)
    image = Image.open('checkcode.gif')
    image.show()
    return check_code

__VIEWSTATE和__EVENTVALIDATION等

通過id來獲取
在這裏插入圖片描述

    soup=bs4.BeautifulSoup(login_page.content,'lxml')
    VIEWSTATE=soup.find('input',id='__VIEWSTATE')['value']
    EVENTVALIDATION=soup.find('input',id='__EVENTVALIDATION')['value']
    VIEWSTATEGENERATOR=soup.find('input',id="__VIEWSTATEGENERATOR")['value']
    PREVIOUSPAGE=soup.find('input',id='__PREVIOUSPAGE')['value']
    check_code_page = 'http://es.bnuz.edu.cn/CheckCode.aspx'
    datas['__VIEWSTATE']=VIEWSTATE
    datas['__EVENTVALIDATION']=EVENTVALIDATION
    datas['TextBox3']=get_check_code(check_code_page,session,headers)
    datas['_VIEWSTATEGENERATOR']=VIEWSTATEGENERATOR
    datas['__PREVIOUSPAGE']=PREVIOUSPAGE

這樣我們就完成了提交請求的data的部分

session.post(url,data=datas,headers=headers)

利用post提交後我們就進入到了學生主頁

進入課程表

請求到學生的主頁之後,我們再用get請求就可以進入到課表界面,不過需要注意的是我們的請求頭需要做一些變化。
Referer是你主頁的URL

headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36',
        'Referer':'http://es.bnuz.edu.cn/xs_main.aspx?xh=******',
        'Host': 'es.bnuz.edu.cn'
    }

我們還需要學生課表界面的URL,每個人的課表界面URL是不一樣的,獲取到的html還需要編碼一下。

  url='http://es.bnuz.edu.cn/jwgl/xskbcx.aspx?xh=123456&xm=%E6%A2%81%E5%BF%97%E6%B5%A9&gnmkdm=N121601'
    result = session.get(url,headers=headers)
    con = result.content.decode('utf-8')#con就是課表界面html了

解析課程表

然後就可以對課表界面的html進行解析了,解析的方法有很多,我就不顯示了。

代碼實現

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import requests
import bs4
from PIL import Image
import csv
import lxml
import io
import codecs

def login(std_id,passw):
    headers={
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36',
    }
    datas={
        'TextBox1':std_id,
        'TextBox2':passw,
        'TextBox3':'',
        'RadioButtonList1':u"學生".encode('gb2312','replace'),
        'Button4_test': '',
        '__VIEWSTATE':'',
        '__EVENTVALIDATION':'',
        '_VIEWSTATEGENERATOR':'',
        '__PREVIOUSPAGE':''
    }
    session=requests.session()#能夠幫我們跨請求保持某些參數,也會在同一個session實例發出的所有請求之間保持cookies。
    url="http://es.bnuz.edu.cn/"
    login_page=session.get(url,headers=headers)
    soup=bs4.BeautifulSoup(login_page.content,'lxml')
    VIEWSTATE=soup.find('input',id='__VIEWSTATE')['value']
    EVENTVALIDATION=soup.find('input',id='__EVENTVALIDATION')['value']
    VIEWSTATEGENERATOR=soup.find('input',id="__VIEWSTATEGENERATOR")['value']
    PREVIOUSPAGE=soup.find('input',id='__PREVIOUSPAGE')['value']
    check_code_page = 'http://es.bnuz.edu.cn/CheckCode.aspx'
    datas['__VIEWSTATE']=VIEWSTATE
    datas['__EVENTVALIDATION']=EVENTVALIDATION
    datas['TextBox3']=get_check_code(check_code_page,session,headers)
    datas['_VIEWSTATEGENERATOR']=VIEWSTATEGENERATOR
    datas['__PREVIOUSPAGE']=PREVIOUSPAGE
    session.post(url,data=datas,headers=headers)
    return session
def get_check_code(checkcode,session,headers):
    img = session.get(checkcode, stream=True, headers=headers)
    with open('checkcode.gif', 'wb') as f:
        f.write(img.content)
    image = Image.open('checkcode.gif')
    image.show()
    check_code = int(input("input code:"))
    return check_code

def into_curriculum(session):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36',
        'Referer':'http://es.bnuz.edu.cn/xs_main.aspx?xh=123456',
        'Host': 'es.bnuz.edu.cn'
    }
    url='http://es.bnuz.edu.cn/jwgl/xskbcx.aspx?xh=123456&xm=123456&gnmkdm=N121601'
    result = session.get(url,headers=headers)
    con = result.content.decode('utf-8')
    return con
    home.close()

stu_id=123456
passwd=123456
homepage=login(stu_id,passwd)
f=into_curriculum(homepage)
soup=bs4.BeautifulSoup(f,'lxml')
soup=soup.find(id='table1')
soup=soup.findAll('li')
for st in soup:
    print(st.getText())

效果圖

原諒我沒排版…
在這裏插入圖片描述

其實還有很多細節我並沒有展開來講啦,比如header和session等等,請自行搜索相關內容吧。

謝謝觀看!

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