基于强智科技教务系统模拟登录,爬取数据(详细技术说明)

版权声明:本文为博主原创文章,未经博主允许不得转载.转载请注明博主链接哈! https://blog.csdn.net/Mmdapl/article/details/80373132

教务系统带验证码模拟登录(基于强智科技系统)

开发背景

上大学以来一直在用强智科技教务系统(很多本科大学的教务管理系统都是基于强智科技的),觉得虽然页面很简单甚至很丑,但是其基本教务管理系统的功能还是具备的完善的,所以当我在接触到数据爬虫的时候,我就想着能不能爬取到学校教务系统上的成绩数据等 .本来数据爬虫,用Python是比较好的,但是我觉得java无所不能,自己也更擅长java,就写了教务系统模拟登录到数据成功爬取并显示的Web Project,已上线;现在详细记录一下我的开发过程

项目分析

1.学校教务系统登录页面(不方便透露,给个基于强智科技教务系统的url:http://newjwxt.bjfu.edu.cn/ 此处地址不针对,如果有不妥,练联系我,会直接修改[直接百度"强智科技"])首先看看的登录的页面的源码截取如下:

<form name="frm" method=post action="/hbgcxy/Logon.do?method=logon" onSubmit="return onSubmint();">
			<div class="login_container">
				<div class="login_content">
					<div class="login_logo"></div>
					<div class="login">
						<table width="430" border="0" cellspacing="0" cellpadding="0">
						<tr><td width="112" align="right">
						<!-- 
						<input type="radio" value="jwxt" checked="checked" name="xtlx"/>教务系统 --> </td>
						<td><!-- <input type="radio" id="xkxt_sel" value="xkxt"  name="xtlx"/>选课系统 --></td></tr>
							<tr>
								<td width="112" height="25" align="right">用户名:</td>
								<td colspan="2">
									<label>
										<input name="USERNAME" type="text" id="userAccount" size="22" class="dl_border" maxlength="32" value="" />
									</label>
								</td>
							</tr>
							<tr>
								<td width="112" height="25" align="right">密  码:</td>
								<td colspan="2">
									<label>
										<input type="password" name="PASSWORD" id="userPassword" value="" size="22" class="dl_border" maxlength="32" />
										<input name="useDogCode" type="hidden" value="" />
										<input name="useDogCode" id="useDogCode" type="hidden">
									</label>
								</td>
							</tr>
							
								<tr>
									<td width="112" height="25" align="right">验证码:</td>
									<td colspan="2">
										<label>
											<input type="text" name="RANDOMCODE" id="RANDOMCODE" style="height:16px;width:93px" size="22" class="dl_border" maxlength="32" />
											<span id="SafeCodeImg"> <img src="/hbgcxy/verifycode.servlet" onclick="ReShowCode()" align="middle" width="62" height="22" /></span>
									</td>
								</tr>
							
							<tr>
								<td width="112" height="25" align="right"> </td>
								<td align="left" colspan=2>
									<font color=red><span id="errorinfo"></span> </font>
								</td>
							</tr>
							<tr>
								<td> </td>
								<td> </td>
								<td height="25" valign=top>
									<table width="100%" border=0>
										<tr>
											<td width="100"><input type="image" src="/hbgcxy/framework/images/login_05.gif" width="76" height="24" /></td>
											<td align="left"><span style="font-size:9pt"><a href="/hbgcxy/framework/enteraccount.jsp" >找回学生密码</a></span></td>
										</tr>
										<tr>
											<td colspan=2> </td>
										</tr>
									</table>
								</td>
							</tr>
							<tr>
								<td height="40"> </td>
								<td colspan="2" style="padding-left:0px;padding-bottom:5px" align="left" valign="bottom">
									在线用户数:
									5
									人  <a  target="_blank" href="http://www.qzdatasoft.com" 
									class="copyright" title="湖南强智科技发展有限公司">技术支持 湖南强智科技发展有限公司</a>
                                                                        <a  target="_blank" href="http://jwgl.hbeu.cn:8088/hbgcxy_xkxt" 
									class="copyright" title="湖南强智科技发展有限公司"><strong><font color="red" size='5'>选课系统由此进入</font></strong></a>
     								</td>
							</tr>
						</table>
					</div>
					<div class="login_dy"></div>
				</div>
		</div>
</form>
通过上面的源码我们可以很清晰的看出:
1.登录页面通过Form表单提交数据,到后台的servlet当中;
2.在Form表单中的关键数据:USERNAME(用户名即学号) PASSWORD(登录密码) RANDOMCODE(验证码)
useDogCode(也应该是个验证码,但是学校教务系统将其属性隐藏,默认提交为空);
3.提交页面的Form表单采用post请求,向后台servlet(http://jwgl.hbeu.cn:8080/hbgcxy/Logon.do?method=logon)提交相应的数据;
4.分析到这里,要想从主页面模拟登录,基本思路就是向后台servlet中,如在教务系统登录页面一样,提交USERNAME,PASSWORD,RANDOMCODE等数据,用于登录;
5.当我有了第四条那样的思路后,我就尝试着登录,此时最大的难题就是,学校教务系统的验证码,它是实时的获取,每一次请求基本都不相同.为此解决验证码问题,我的思路是:
  • 采用人工智能识别,调用别人的接口(普遍收费),进行在线识别

  • 采用之前在博客上面看到的orc识别,也就是把基本的图像识别java项目部署到自己的爬虫项目中,在运行项目的时候识别

  • 采用人工识别,就是实时的获取servlet响应的验证码,然后在登录的时候自己识别,提交,模拟登录

  • 来来我觉得人工识别过于直接,效率和体验度不是很好,就想着能不能通过简单的图片爬取 对应的验证码,将写到数据库中,然后通过一一对应来获取验证码上面的数据.(结果尝试失败,主要原因是servlet是根据系统时间在线随机生成验证,做成数据库很难,需要统计)

批量下载验证的源码

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import org.jsoup.Jsoup;
import org.jsoup.Connection.Method;
import org.jsoup.Connection.Response;
public class ImgUtil {
    /**
     * 将字节流转换成文字流
     * 
     * @param filename
     * @param data
     * @throws Exception
     */
    public static void saveFile(String filename, byte[] data) {

        if (data != null) {
            String filepath = filename;
            File file = new File(filepath);
            if (file.exists()) {
                file.delete();
            }
            try {
                FileOutputStream fos = new FileOutputStream(file);
                fos.write(data, 0, data.length);
                fos.flush();
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
	/**
	 * 
	 * @param path
	 * @param codeUrl
	 * @throws IOException
	 */
	public void getSafeCode(String path,String codeUrl) throws IOException {
		Response response = Jsoup.connect(codeUrl).ignoreContentType(true)  
				.userAgent("Mozilla").method(Method.GET).timeout(3000).execute();
		//cookie = response.cookies();
		//System.out.println("cookie:" + cookie);
		byte[] bytes = response.bodyAsBytes();
		ImgUtil.saveFile(path, bytes);
		System.out.println("验证码保存地址:" + path);
	}
}

上面源码采用jsoup的批量爬虫,调用相关类就可以

最后,关于验证码,我还是采用的普通的人工识别,在访问自己的Web Project的登录页面的时候,实时的通过验证码获取图片,以及对应的(Cookie)

/**
	 * 下载验证码 保存Cookie
	 * 
	 * @throws IOException
	 */
	public void getSafeCode(String path) throws IOException {
		Response response = Jsoup.connect(url_safecode).ignoreContentType(true) // 获取图片需设置忽略内容类型
				.userAgent("Mozilla").method(Method.GET).timeout(3000).execute();
		cookie = response.cookies();
		System.out.println("cookie:" + cookie);
		byte[] bytes = response.bodyAsBytes();
		ImgUtil.saveFile(path, bytes);
		System.out.println("保存验证码到:" + path);
		
		//获取header
		Map<String, String> headers=response.headers();
		for (Map.Entry<String, String> entry : headers.entrySet()) {  
			if (entry.getKey().equals("Set-Cookie")) {
				System.out.println(entry.getValue()+"!!!!!!!!!QWQWEWQEQWE");
			}
			    System.out.println(entry+"!!!!!!!!!!!!!!!!!!!!!!!!!!!");
		} 
    }

对于cookie可以尝试百度,就相当于你在登录成功之后的系统后台唯一认证的身份


将cookie保存下来,基本思路就是要实现cookie与验证码图片的一一对应关系(在登录成功之后,该Cookie是我们在做成绩,信息爬取的唯一身份标识)

获取Cookie和验证码后,便可写前端登录login.jsp的UI,通过Form表单提交数据

采用AmazingUI前端框架


在html中引入AmazingUI的js,Css样式

<meta name="mobile-web-app-capable" content="yes">
<link rel="icon" sizes="192x192" href="assets/i/app-icon72x72@2x.png">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="Amaze UI" />
<meta name="msapplication-TileImage"
	content="assets/i/app-icon72x72@2x.png">
<meta name="msapplication-TileColor" content="#0e90d2">
<link rel="stylesheet" href="http://142vip.cn/bootstrap/css/bootstrap.min.css"/>
<link rel="stylesheet"
	href="http://cdn.amazeui.org/amazeui/2.7.2/css/amazeui.css" />
<link rel="stylesheet"
	href="http://cdn.amazeui.org/amazeui/2.7.2/css/amazeui.min.css" />
<script type="text/javascript"
	src="http://cdn.amazeui.org/amazeui/2.7.2/js/amazeui.js"></script>
<script type="text/javascript"
	src="http://cdn.amazeui.org/amazeui/2.7.2/js/amazeui.min.js"></script>
<script type="text/javascript"
	src="http://cdn.amazeui.org/amazeui/2.7.2/js/amazeui.ie8polyfill.js"></script>
<script type="text/javascript"
	src="http://cdn.amazeui.org/amazeui/2.7.2/js/amazeui.ie8polyfill.min.js"></script>
<script type="text/javascript"
	src="http://cdn.amazeui.org/amazeui/2.7.2/js/amazeui.widgets.helper.js"></script>
<script type="text/javascript"
	src="http://cdn.amazeui.org/amazeui/2.7.2/js/amazeui.widgets.helper.min.js"></script>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
整体UI布局
<div class="am-u-lg-centered am-u-lg-5 am-margin-top-xl">
	<div class="am-u-sm-12 am-text-middle am-margin-top-xl am-margin-bottom-xl"
	align="center">
	<img class="am-circle" src="img/hbeu.jpg" width="140px"	height="140px" /><br> 
		<label class="am-text-xl ">教务系统成绩查询</label><small>Beta版</small></div>
			<form class="am-form am-form-horizontal" action="query"method="post" id="data">
					<div class="am-form-group">
						<label
							class="am-u-sm-2 am-form-label am-text-primary am-text-nowrap">学   号:</label>
						<div class="am-u-sm-10 am-margin-top-xs">
							<input type="text" id="username" name="username"
								placeholder="请输入学号" style="font-size: 14px">
						</div>
					</div>

					<div class="am-form-group">
						<label
							class="am-u-sm-2 am-form-label am-text-primary am-text-nowrap">密   码:</label>
						<div class="am-u-sm-10 am-margin-top-xs">
							<input type="password" id="password" name="password"
								class="am-text-sm" placeholder="请输入密码" style="font-size: 14px">
						</div>
					</div>
<div class="am-form-group am-margin-bottom-xl">
	<label class="am-u-sm-2 am-form-label am-text-primary am-text-nowrap">验证码:</label>
		<div class="am-u-sm-6 am-text-center am-margin-top-xs">
			<input type="text" class="am-text-bottom am-text-xs" id="code"
					name="code" placeholder="请输入验证码" style="font-size: 14px">
</div>
<div class="am-u-sm-4 am-margin-top-sm ">
		<img src="http://localhost:8080/JsxtScore/verifycode.png"alt="请尝试刷新" style="font-size: 10px" />
</div>
		</div>
			<div class="am-form-group am-margin-top-xl">
				<div class="am-u-sm-12 am-text-middle ">
					<button type="button" class="am-btn am-btn-primary am-btn-block"
								onclick="btnSubmit()">登录查询</button>
						</div>
					</div>
				</form>
	<div class="am-u-sm-12 am-text-right am-text-sm">
		<p class="am-text-middle">
			<a href="#" class="am-secondary am-icon-qq am-margin-right-xs  ">QQ登录</a>
			<a href="#" class="am-secondary am-icon-weixin am-margin-left-xs">微信登录</a>
			<a href="#" class="am-secondary am-icon-share am-margin-left-xs">二维码分享</a>
		</p>
	</div>
		<p class="am-text-sm am-text-center am-margin-top-xl">计算机学院李朓
					版权所有&copy;2018</p>
		<p class="am-text-right am-u-sm-12">
		<a href="http://www.142vip.cn"><strong class="am-text-sm">发现更多>></strong></a>
		</p>
</div>

不作过多说明,还是看源码比较舒服

手机UI显示

登录逻辑:

1.在前面已经获取cookie和验证码,可尝试登录逻辑


将表单Form中的数据分别通过jsoup提供的Connection类来尝试Http请求,提交数据(将数据放在HashMap的数据集合中)

通过尝试后的connect对象来获取对应响应页面的源码

将解析的成绩存入到数据库中,可以访问博客:https://blog.csdn.net/mmdapl/article/details/80288861

在这个项目中,我从http的请求到,html的解析都是使用jsoup的jar包,感觉很好,特别在解析html网页源码的时候,提供很多帮助

整个项目的基本层次

功能有:

  1. 教务系统验证码获取(将获取的验证码存放在自己的Tomcat服务器中,访问)

    链接地址:http://www.142vip.cn/sources/verifycode.png

  2. 教务系统中个人信息的获取(部分个人信息)


3.教务系统中学习成绩的获取(部分成绩信息)




博客说明:

    1.关于本文章,是由于个人编程爱好,利用课外时间完成整个项目的,博客是在整理开发笔记的过程中总结而来,部分地方可能有写争议,如果你有幸看到这篇文章,不要随意转载,对于有不好的地方,可以及时提出来,我会及时修改,如果有任何给您带来不便的,请及时留言和我联系;另外不要将本项目用于非法谋利;欢迎大家交流学习;

     2.如果你对本文章感兴趣,可以留言联系我,互相交流,也可访问我的网站,天南地北支持一波访问量,谢谢!


兄弟们,微信扫一扫


项目演示地址:教务系统模拟登录(带验证码) 天南地北,点赞支持一波...

展开阅读全文

没有更多推荐了,返回首页