臭烂代码蜕变 | python爬取教务管理系统成绩(初版)

前言

比赛中自己的Python代码真的是又臭又烂,花一天学习re、Beautifulsoup、request….。写个爬虫脚本练练手.

简单分析

通过抓包分析,点击查询会向服务器发送如下参数,而__VIEWSTATE参数访问http://jwgl.fafu.edu.cn/(gbwqej55d4yuib45ubml4kiy)/xscjcx_dq_fafu.aspx?xh=3176017015&xm=%D5%C5%C1%A6&gnmkdm=N121605可以从html中提取

1566843562248

代码

# -*- coding: UTF-8 -*-
import re
import requests
from bs4 import BeautifulSoup

url="http://jwgl.fafu.edu.cn/(gbwqej55d4yuib45ubml4kiy)/xscjcx_dq_fafu.aspx?xh=3176017015&xm=%D5%C5%C1%A6&gnmkdm=N121605"
headerspost={
'Host': 'jwgl.fafu.edu.cn',
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36',
'Referer': 'http://jwgl.fafu.edu.cn/(32yiyp45ngivva55fcwg1i55)/xscjcx_dq_fafu.aspx?xh=3176017015&xm=%D5%C5%C1%A6&gnmkdm=N121605'
}

headersget={
'Host': 'jwgl.fafu.edu.cn',
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36',
'Referer': 'http://jwgl.fafu.edu.cn/(cxtcui55vpjjaxvewtwl1045)/xs_main.aspx?xh=3176017015'
}

# 获取关键post数据,抓包发现该两个__VIEWSTATE、__VIEWSTATEGENERATOR字段对查询结果产生影响
rep1=requests.get(url=url,headers=headersget)
m=re.findall(r'(?<=value=").+"',rep1.text)
__VIEWSTATE=m[0].replace('"','')
__VIEWSTATEGENERATOR=m[1]


# 年份,可更改
ddlxn='2018-2019'
# 学期,可更改
ddlxq='2'
btnCx="+%B2%E9++%D1%AF+"

data={
	'__EVENTTARGET':'',
	'__EVENTARGUMENT':'',
	'__VIEWSTATE':__VIEWSTATE,
	'__VIEWSTATEGENERATOR':__VIEWSTATEGENERATOR,
	'ddlxn':ddlxn,
	'btnCx':btnCx,
	'ddlxq':ddlxq
}
rep=requests.post(url,headers=headerspost,data=data)
rep.encoding=rep.apparent_encoding
soup=BeautifulSoup(rep.text,'xml')

# 创建数组原因是BeautifulSoup产生的结果不适于操作
arr=[]
arr1=[]
arr2=[]
arr3=[]

# 获取所有td标签
td=soup.find_all('td')
for i in td:
    arr.append(i.string)

# 获取课程代码
td1=soup.find_all('td',string=re.compile(r'^\d{3,9}$'))
count=len(td1)
for i in td1:
    arr1.append(i.string)


# 获取成绩
td2=soup.find_all(string=re.compile(r'^\d{2}(.\d)?$'))
for i in td2:
    arr2.append(i)

# 课程代码索引加+1后为课程名称
for i in range(count):
    arr3.append(td[arr.index(arr1[i])+1].string)



for i in range(count):
    print("{0:<14}\t{1:<10}".format(arr3[i],arr2[i]))

1566843390711