Open justtreee opened 6 years ago
环境:chrome,python 3.5 一、正方教务管理系统 1. 目标分析
环境:chrome,python 3.5
首先可以看到我们需要填写以下字段:
用户名 密码 验证码 身份选择
需要注意的就是验证码: 可以知道验证码是以图片的方式浮现在文本框上的。这里选择找到验证码的图片链接,并下载到本地,通过用户手动输入验证码来完成登录。
之后可以尝试一下图像识别的第三方库,实现自动填写验证码。
对验证码右键单击检查,可直接定位在验证码的相应信息上。
检查
得到验证码的图片链接:
jw.****.edu.cn/default2.aspx/CheckCode.aspx
在chrome下按F12打开开发者工具
chrome
F12
这里给一个技巧,我们可以先故意输入一个 错误的值 来追踪一下我们究竟post了哪些值 打开 Chrome开发者工具 --- Networks --- 勾选 Preserve log 输入一些值,点击 登录按钮, 在点开右边的 Headers 拉倒最后的 FromData: 这里就是我们提交数据:
这个字典里,我们很容易可以看到我们需要自己填写的值: post的数据一般是通过键值对的形式传到服务器的,一般是字典或json格式
而第一个数据是如何得到的?在登录界面的html页面中。
可见第一个数据在登录界面html中,我们模拟登录时把这个数据提出来。就行了。
这一长串随机的值,实际上是正方系统的一个简单的验证手段。
通过浏览器登录之后,进入 /xs_main.aspx?xh=********** 页面,再转入课表页面,地址栏的网页链接并没有变化,但真正的课表链接藏在html里面。同理在课表处右键检查定位到html中
/xs_main.aspx?xh=**********
html
#-*-coding:utf-8-*- import os import re from lxml import etree import requests import sys from bs4 import BeautifulSoup from PIL import Image #初始参数,自己输入的学号,密码。 studentnumber = input("学号: ") password = input("密码: ") #得到__VIEWSTATE的值。 s = requests.session() url = "http://jw.****.edu.cn/default2.aspx" response = s.get(url) selector = etree.HTML(response.content) __VIEWSTATE = selector.xpath('//*[@id="form1"]/input/@value')[0] #获取验证码并下载到本地 imgUrl = "http://jw.****.edu.cn/CheckCode.aspx?" imgresponse = s.get(imgUrl, stream=True) #print (s.cookies) image = imgresponse.content DstDir = os.getcwd()+"\\" try: with open(DstDir+"tcode.jpg" ,"wb") as jpg: jpg.write(image) except IOError: print("IO Error\n") finally: jpg.close # 打开验证码图片 image = Image.open('{}/tcode.jpg'.format(os.getcwd())) image.show() #手动输入验证码 code = input("验证码: ") #构建post数据 data = { "__VIEWSTATE":__VIEWSTATE, "txtUserName":studentnumber, "TextBox2":password, "txtSecretCode":code, "Button1":"", } #提交表头,里面的参数是电脑各浏览器的信息。模拟成是浏览器去访问网页。 headers = { "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36", } #登陆教务系统 response = s.post(url,data=data,headers=headers) print ("成功进入") #得到登录信息 def getInfor(response,xpath): content = response.content.decode('gb2312') #网页源码是gb2312要先解码 selector = etree.HTML(content) infor = selector.xpath(xpath)[0] return infor #获取学生基本信息 text = getInfor(response,'//*[@id="xhxm"]/text()') text = text.replace(" ","") print (text) #获取课表,kburl是课表页面url,为什么有个Referer参数,这个参数代表你是从哪里来的。就是登录后的主界面参数。这个一定要有。 kburl = "http://jw.****.edu.cn/xskbcx.aspx?xh="+studentnumber+"&xm=%D5%C5%B8%DB&gnmkdm=N121603" headers = { "Referer":"http://jw.****.edu.cn/xs_main.aspx?xh="+studentnumber, "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36", } response = s.get(kburl,headers=headers) #html代表访问课表页面返回的结果就是课表。下面做的就是解析这个html页面。 html = response.content.decode("gb2312") selector=etree.HTML(html) content = selector.xpath('//*[@id="Table1"]/tr/td/text()') for each in content: print (each)
校体育部这个网站有点非主流,与csdn等博客上最常见的教务系统登录不太一样,是个很好的练手对象。
首先是通过Fiddler 4对目标网站进行登录抓包(应该是这个词吧)。
Fiddler 4
关键点1: 体育部的登陆页面并不是/security/login.do,而是/login.do。 关键点2: 在输入账号密码之后,还有btnlogin.x与btnlogin.y这两个属性,大胆猜测这是点击按钮的动作,而后面值就是横纵坐标。
/security/login.do
/login.do
btnlogin.x
btnlogin.y
import urllib.request, urllib.parse, urllib.error import http.cookiejar import requests from bs4 import BeautifulSoup import bs4 LOGIN_URL = 'http://211.69.129.116:8501/login.do' # ===========关键点:体育部网站的真正登陆页面并不是网站那栏,在fiddler中显示为该网址=========== get_url = 'http://211.69.129.116:8501/jsp/menuForwardContent.jsp?url=stu/StudentSportModify.do' #get_url = 'http://211.69.129.116:8501/' # 利用cookie请求访问另一个网址 values = {'action': 'username', 'username': '2016317200113', 'password': '888888', 'btnlogin.x': '30', 'btnlogin.y': '11'} # ===========关键点:在fiddler的action中还有两行btnlogin的信息,将这个点击按钮的动作加入到values中=========== postdata = urllib.parse.urlencode(values).encode() user_agent = r'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36' headers = {'User-Agent': user_agent} cookie_filename = 'cookie_jar.txt' cookie_jar = http.cookiejar.MozillaCookieJar(cookie_filename) handler = urllib.request.HTTPCookieProcessor(cookie_jar) opener = urllib.request.build_opener(handler) request = urllib.request.Request(LOGIN_URL, postdata, headers) try: response = opener.open(request) html = response.read().decode() #print(response.read().decode()) except urllib.error.URLError as e: print(e.code, ':', e.reason) #================html格式化================ soup = BeautifulSoup(html) print(soup.prettify()) #========================================== # TODO: Creat List ulist = [] soup = BeautifulSoup(html, "html.parser") for tr in soup.find('tbody').children: if isinstance(tr, bs4.element.Tag): tds = tr('td') ulist.append([tds[0].string, tds[1].string]) print("==================LIST======================") for i in range(5): u = ulist[i] print("{:^10}\t{:^6}", format(u[0], u[1])) #=================unfinished=================
但是获取的还是原始的html文本,没有依据标签进行数据提取。 未完待续
参考链接: 从零开始写Python爬虫、 抓取课程表
首先可以看到我们需要填写以下字段:
需要注意的就是验证码: 可以知道验证码是以图片的方式浮现在文本框上的。这里选择找到验证码的图片链接,并下载到本地,通过用户手动输入验证码来完成登录。
2. 数据抓取
(1) 抓取验证码
对验证码右键单击
检查
,可直接定位在验证码的相应信息上。得到验证码的图片链接:
jw.****.edu.cn/default2.aspx/CheckCode.aspx
(2) 抓取post数据
在
chrome
下按F12
打开开发者工具这个字典里,我们很容易可以看到我们需要自己填写的值: post的数据一般是通过键值对的形式传到服务器的,一般是字典或json格式
而第一个数据是如何得到的?在登录界面的html页面中。
可见第一个数据在登录界面html中,我们模拟登录时把这个数据提出来。就行了。
(3) 获取课表
通过浏览器登录之后,进入
/xs_main.aspx?xh=**********
页面,再转入课表页面,地址栏的网页链接并没有变化,但真正的课表链接藏在html
里面。同理在课表处右键检查
定位到html
中(4) 代码
(5) 结果
TODO: 3. 验证码的自动识别
二、校体育部网站
校体育部这个网站有点非主流,与csdn等博客上最常见的教务系统登录不太一样,是个很好的练手对象。
1. 模拟登录
首先是通过
Fiddler 4
对目标网站进行登录抓包(应该是这个词吧)。登录成功并获取首页html
数据提取
但是获取的还是原始的html文本,没有依据标签进行数据提取。 未完待续