您的位置:首页 > 编程语言 > Python开发

python爬虫登录正方教务管理系统获取成绩数据

2017-07-06 21:28 836 查看
本程序以四川理工学院教务管理系统为例。。。。

准备工作:1.ruquests库的使用(或者urllib也可行)

    2.正则表达式的书写

                    3.HTTP通信基础

                    4.一些解析库的使用

准备一个浏览器监视工具,这里我是用的是fiddler下载地址点击打开链接

登录官网获取到登录系统url:http://61.139.105.138/default2.aspx



这里可以知道浏览器是先请求登录页面,让后转到去获取验证码图片。

仔细分析验证码连接发现:



这个请求方式是get但包含有cookies

所以模拟登录前获取验证码时需要带上cookies否则登录会一直提示验证码错误



查看发送的请求


__VIEWSTATE可以在登录页面的脚本中捕捉到 后面的数据便是post请求需要带上的数据

最后对于网页上的验证码问题,这里选择下载验证码图片并自动打开。

下面贴上模拟登录的代码

import requests
import re
from html.parser import *
import urllib.request
import os
x=[]
state=[]
class Scraper(HTMLParser):
def handle_starttag(self,tag,attrs):
if tag=='img':#验证码
attrs=dict(attrs)
if(attrs.__contains__('id')):
x.append(attrs["src"])
if tag=='input':#viewstate
attrs=dict(attrs)
if attrs.__contains__('name'):
if attrs['name']=='__VIEWSTATE':
state.append(attrs['value'])

webpage=requests.get(url="http://61.139.105.138/default2.aspx")
Cookie=webpage.cookies#获取网页cookies
date=webpage.text
parser=Scraper()
parser.feed(date)
headers={
'User-Agent':r'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0;  TheWorld 7)',
}
while True:
url="http://61.139.105.138/CheckCode.aspx"#验证码所在连接
pic=requests.get(url,cookies=Cookie,headers=headers)
if os.path.exists(r'f://yanzheng.jpg'):
os.remove(r'f://yanzheng.jpg')
with open(r'f://yanzheng.jpg','wb')as f:
f.write(pic.content)
f.close()
username=input("输入用户名: ")
password=input("输入密码 ")

os.startfile(r'f:yanzheng.jpg')
ycode=input("输入弹出的验证码: ")

payload={
'__VIEWSTATE':state[0],
'txtUserName':username,
'TextBox2':password,
'txtSecretCode':ycode,
'RadioButtonList1':'%D1%A7%C9%FA',
'Button1':"",
'lbLanguage':'',
'hidPdrs':'',
'hidsc':'',
}
Log_in=r"http://61.139.105.138/default2.aspx"

r=requests.post(url=Log_in,data=payload,headers=headers,cookies=Cookie)
#用正则算了
pat=r'<title>(.*?)</title>'#获取标题的正则表达式
x=re.findall(pat,r.text)
if(x[0]=="欢迎使用正方教务管理系统!请登录"):
print("登陆失败")
albert="defer>alert\('(.*?)'\)"
err=re.findall(albert,r.text)
print(err[0])
else:
print("登陆成功")


过程中遇到需要判断登录是否成功,这里选择识别标记字符,我这边抓取了网页的标题,如果不成功标题就会是"欢迎使用正方教务管理系统!请登录"

在登录失败的情况下依然可以通过正则表达式获取登录失败信息

最后便是进入成绩查询界面,依旧先通过fiddler观察浏览器的行为:



    可以看出get请求相关信息是学号,姓名,项目代码(姓名可以在登录页面抓取)

    值得注意的是headers中必须含有referer否则会被弹出

    下面贴出相关代码:

#抓一下名字
catch='<span id="xhxm">(.*?)</span></em>'
name=re.findall(catch,r.text)
name=name[0]
name=name[:-2]
print(name)
break
name=str(name).replace(r'\x','%')#扩大适用性
name=name.upper()
name=name[2:]

lheaders={
'User-Agent':r'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0;  TheWorld 7)',
'Referer':'http://61.139.105.138/xs_main.aspx?xh='+username#扩大适用性
}
html=requests.get("http://61.139.105.138/xscjcx_dq.aspx?xh="+username+"&xm="+name+"&gnmkdm=N121605",cookies=Cookie,headers=lheaders)
#最后处理成绩信息
selectall=r'<td>(.*?)</td>'*17
result=re.findall(selectall,html.text)
xm=result[0]#项目分离
forma=[]
temp=''
for i in range(17):forma.append('')#17位的数据存放处理好的数据
for index in range(17):
for item in result:
temp=format("% -15s"%str(item[index]).strip())
forma[index]+=temp

for each in forma:
print(each)
input("查询结束按下任意键退出")


这就是整个爬虫实现的过程,允许相关输入错误后再次输入

最后贴上整个项目代码:

import requests
import re
from html.parser import *
import urllib.request
import os
import csv
x=[]
state=[]
class Scraper(HTMLParser):
def handle_starttag(self,tag,attrs):
if tag=='img':#验证码
attrs=dict(attrs)
if(attrs.__contains__('id')):
x.append(attrs["src"])
if tag=='input':#viewstate
attrs=dict(attrs)
if attrs.__contains__('name'):
if attrs['name']=='__VIEWSTATE':
state.append(attrs['value'])

webpage=requests.get(url="http://61.139.105.138/default2.aspx")
Cookie=webpage.cookies#获取网页cookies
date=webpage.text
parser=Scraper()
parser.feed(date)
headers={
'User-Agent':r'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0; TheWorld 7)',
}
while True:
url="http://61.139.105.138/CheckCode.aspx"#验证码所在连接
pic=requests.get(url,cookies=Cookie,headers=headers)
if os.path.exists(r'f://yanzheng.jpg'):
os.remove(r'f://yanzheng.jpg')
with open(r'f://yanzheng.jpg','wb')as f:
f.write(pic.content)
f.close()
username=input("输入用户名: ")
password=input("输入密码 ")

os.startfile(r'f:yanzheng.jpg')
ycode=input("输入弹出的验证码: ")

payload={
'__VIEWSTATE':state[0],
'txtUserName':username,
'TextBox2':password,
'txtSecretCode':ycode,
'RadioButtonList1':'%D1%A7%C9%FA',
'Button1':"",
'lbLanguage':'',
'hidPdrs':'',
'hidsc':'',
}
Log_in=r"http://61.139.105.138/default2.aspx"

r=requests.post(url=Log_in,data=payload,headers=headers,cookies=Cookie)
#用正则算了
pat=r'<title>(.*?)</title>'#获取标题的正则表达式
x=re.findall(pat,r.text)
if(x[0]=="欢迎使用正方教务管理系统!请登录"):print("登陆失败")
else:
print("登陆成功")
#抓一下名字
catch='<span id="xhxm">(.*?)</span></em>'
name=re.findall(catch,r.text)
name=name[0]
name=name[:-2]
print(name)
break
name=str(name).replace(r'\x','%')#扩大适用性
name=name.upper()
name=name[2:]

lheaders={
'User-Agent':r'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0; TheWorld 7)',
'Referer':'http://61.139.105.138/xs_main.aspx?xh='+username#扩大适用性
}
html=requests.get("http://61.139.105.138/xscjcx_dq.aspx?xh="+username+"&xm="+name+"&gnmkdm=N121605",cookies=Cookie,headers=lheaders)
#最后处理成绩信息
selectall=r'<td>(.*?)</td>'*17
result=re.findall(selectall,html.text)
xm=result[0]#项目分离
forma=[]
csvfile=open('f://result.csv','w',newline='')
writer=csv.writer(csvfile)
temp=''
for i in range(17):forma.append('')#17位的数据存放处理好的数据
for index in range(17):
for item in result:
temp=format("% -15s"%str(item[index]).strip())
forma[index]+=temp

for each in forma:
print(each)

for num,item in enumerate(result):
for index,value in enumerate(item):#处理下result里面的无规则数据
if value==" ":
result[num][index]=''

for item in result:
writer.writerow(item)
csvfile.close()
input("爬虫完成,结果存在F盘result.csv文件下")
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: