Android实现正方系统的登录以及课程表,成绩获取和空课室的查询(二)

来源:互联网 发布:为什么需要软件测试 编辑:程序博客网 时间:2024/03/29 13:48

      上篇说了怎么实现登录的原理以及实现,接下来就是实现如何获得课程表,成绩以及空课室的信息了。其实原理很简单,如果你真的有认真看上一篇的登录实现步骤的话,其实很快就会得到结果。

       因为原理都差不多,这里我只说如何获取课程表的信息,因为其他的功能都和这个功能的数据获取差不多。

      那么下面就来进行对课程表的获取把!

      登录正方教务系统,然后点击"学生个人课表",我们可以看到以下这个界面

    

   我们这时候就要用到上篇所教的HttpWatch进行抓包,注意要在点击"学生个人课表"进行Record,接下来我们就会获得以下信息

    

    点击这个post请求,我们可以看到

     

    是不是觉得很熟悉,没错,这个就是正方教务系统获取特定数据所需要的参数,所以按照我们之前那样把这些参数都加入到post中就可以得到对应的数据

     那么我们看看我们究竟会得到什么数据?

    

   

    之前没碰过html的人可能会惊呆了,这究竟是什么东西?如果觉得看到这个不知道是什么,请自己看下html,这里就不说了。

    现在我们看上去可以看到我们的信息在里面了,但是里面夹杂着很多我们不需要的东西,那我们究竟要怎么获取到我们需要的数据?

    在我接触java爬虫的时候,我也不知道究竟要怎么处理下载下来的html,但是有一天看到了hongyang大神的博客,学习了基本的java爬虫以及如何获取里面的信息,真的

    觉得收益无穷,也是因为看了他的博客,我才会开启了这几个信息对java爬虫的兴趣,并进行对学校新闻的爬取,当然也包括这个。

    所以如果这里看完之后觉得对html的数据解析不够明白,可以看一下hongyang大神的博客学习学习。


    说了这么多废话,那么究竟怎么才能获取到html中的特定数据呢?没错,就是jsoup。通过jsoup进行html的解析。其实通过jsoup进行对html进行解析没什么难度,难度只是

在于你要分析你下载下来的html,然后根据一些标签的特点或者规律进行适当的解析,这是我在实现解析时候的越到的一个大困难。无疑,解析我学校的课程表真的很痛苦,因为它有些格式不是很好,所以解析的时候我尽量要避免。

     下面来说一下究竟怎么解析html:

      

public class ExtractService{/** * @param rule * @return */public static List<NewsInfo> extract(Rule rule){// 进行对rule的必要校验validateRule(rule);List<NewsInfo> datas = new ArrayList<NewsInfo>();<span style="font-family: Arial, Helvetica, sans-serif;"> </span>NewsInfo data = null;try{/** * 解析rule */String url = rule.getUrl();String[] params = rule.getParams();String[] values = rule.getValues();String resultTagName = rule.getResultTagName();int type = rule.getType();int requestType = rule.getRequestMoethod();List<NameValuePair> params1 = null;if (params != null){ params1=new ArrayList<NameValuePair>();for (int i = 0; i < params.length; i++){NameValuePair nameValuePair=new BasicNameValuePair(params[i], values[i]);params1.add(nameValuePair);}}Document doc=null;if(params1!=null){String html=BaseApplication.getSearchHtml(url, params1); doc=Jsoup.parse(html);                              //这里解析html,获取到<span style="font-family: Arial, Helvetica, sans-serif;">Document </span>}else{String html=BaseApplication.getHtml(url); doc=Jsoup.parse(html);}
                       <span style="color:#ff0000;">//这以上的代码只是为了获取html,关键代码就只有一句(<span style="font-family: Arial, Helvetica, sans-serif;">doc=Jsoup.parse(html); )这句,重点是在下面</span></span>//处理返回数据Elements results = new Elements();switch (type)            //我们可以看到html有很多class,id,selection等标签,所以通过switch来选出你需要获得的标签,然后获取到你所指定的那个范围,这样就更进一步忽略掉没用的信息了,这里需要自己看下网页源码理解下,尤其对html不熟的。{case Rule.CLASS:results = doc.getElementsByClass(resultTagName);break;case Rule.ID:Element result = doc.getElementById(resultTagName);results.add(result);break;case Rule.SELECTION:results = doc.select(resultTagName);break;default://当resultTagName为空时默认去body标签if (TextUtil.isEmpty(resultTagName)){results = doc.getElementsByTag("body");}}                        //以下就是对指定"body"范围中的内容进行解析,每个网页都不同,所以你要根据你自己需求去获取for (Element result : results){Elements links = result.getElementsByTag("p");for (int i = 0; i < links.size(); i++){Element unit_ele = links.get(i);Element link = unit_ele.getElementsByTag("a").get(0);String content=link.text();String href = link.attr("href");String title = link.attr("title");Element h4_ele = unit_ele.getElementsByTag("span").get(0);String from = h4_ele.attr("title");Element h4_ele1 = unit_ele.getElementsByTag("span").get(1);String date = h4_ele1.text();data = new NewsInfo();data.setLinkHref(href);data.setTitle(title);data.setFrom(from);data.setDate(date);data.setContent(content);datas.add(data);}}} catch (IOException e){e.printStackTrace();}return datas;}/** * 对传入的参数进行必要的校验 */private static void validateRule(Rule rule){String url = rule.getUrl();if (TextUtil.isEmpty(url)){throw new RuleException("url不能为空?");}if (!url.startsWith("http://")){throw new RuleException("url的格式不正确?");}if (rule.getParams() != null && rule.getValues() != null){if (rule.getParams().length != rule.getValues().length){throw new RuleException("参数的键值对个数不匹配!");}}}}
public class Rule{<span style="white-space:pre"></span>/**<span style="white-space:pre"></span> * 链接<span style="white-space:pre"></span> */<span style="white-space:pre"></span>private String url;<span style="white-space:pre"></span>/**<span style="white-space:pre"></span> * 参数集合<span style="white-space:pre"></span> */<span style="white-space:pre"></span>private String[] params;<span style="white-space:pre"></span>/**<span style="white-space:pre"></span> * 参数对应的�??<span style="white-space:pre"></span> */<span style="white-space:pre"></span>private String[] values;<span style="white-space:pre"></span>/**<span style="white-space:pre"></span> * 对返回的HTML,第�?次过滤所用的标签,请先设置type<span style="white-space:pre"></span> */<span style="white-space:pre"></span>private String resultTagName;<span style="white-space:pre"></span>/**<span style="white-space:pre"></span> * CLASS / ID / SELECTION<span style="white-space:pre"></span> * 设置resultTagName的类型,默认为ID <span style="white-space:pre"></span> */<span style="white-space:pre"></span>private int type = ID ;<span style="white-space:pre"></span><span style="white-space:pre"></span>/**<span style="white-space:pre"></span> *GET / POST<span style="white-space:pre"></span> * 请求的类型,默认GET<span style="white-space:pre"></span> */<span style="white-space:pre"></span>private int requestMoethod = GET ; <span style="white-space:pre"></span><span style="white-space:pre"></span>public final static int GET = 0 ;<span style="white-space:pre"></span>public final static int POST = 1 ;<span style="white-space:pre"></span><span style="white-space:pre"></span>public final static int CLASS = 0;<span style="white-space:pre"></span>public final static int ID = 1;<span style="white-space:pre"></span>public final static int SELECTION = 2;<span style="white-space:pre"></span>public Rule()<span style="white-space:pre"></span>{<span style="white-space:pre"></span>}<span style="white-space:pre"></span><span style="white-space:pre"></span>public Rule(String url, String[] params, String[] values,<span style="white-space:pre"></span>String resultTagName, int type, int requestMoethod)<span style="white-space:pre"></span>{<span style="white-space:pre"></span>super();<span style="white-space:pre"></span>this.url = url;<span style="white-space:pre"></span>this.params = params;<span style="white-space:pre"></span>this.values = values;<span style="white-space:pre"></span>this.resultTagName = resultTagName;<span style="white-space:pre"></span>this.type = type;<span style="white-space:pre"></span>this.requestMoethod = requestMoethod;<span style="white-space:pre"></span>}
    上面只是想帮助你理解一下详细的jsoup解析是怎样的,接下来我放源码上来把

   

/**     * 查询个人课表方法     *                                                            * @param xnd     * @param xqd     * @throws ClientProtocolException     * @throws IOException     * @return      */    public static  HashMap<String, HashMap<Integer, ArrayList<Course>>> queryStuCourse(String xnd, String xqd)            throws ClientProtocolException, IOException {     HttpClient client = new DefaultHttpClient();              int lastIndexOf = stuName.lastIndexOf("同学");     if(lastIndexOf!=-1)      stuName = stuName.substring(0, lastIndexOf);      System.out.println(stuName);             String newQueryStuCourseUrl = queryStuCourseUrl + stuNumber + "&xm="                + stuName + queryStuCourseGnmkd;                System.out.println(newQueryStuCourseUrl);                String viewState = IOUtils.getViewState(newQueryStuCourseUrl, Cookie,                mainUrl + stuNumber);        HttpPost queryStuCoursePost = new HttpPost(newQueryStuCourseUrl);                queryStuCoursePost.getParams().setParameter(ClientPNames.HANDLE_REDIRECTS, false);                List<NameValuePair> stuCoursePair = new ArrayList<NameValuePair>();        stuCoursePair.add(new BasicNameValuePair("__EVENTTARGET", "xqd"));        stuCoursePair.add(new BasicNameValuePair("__EVENTARGUMENT", ""));        stuCoursePair.add(new BasicNameValuePair("__VIEWSTATE", viewState));        stuCoursePair.add(new BasicNameValuePair("xnd", xnd));        stuCoursePair.add(new BasicNameValuePair("xqd", xqd));        queryStuCoursePost.setHeader("Cookie", Cookie);        queryStuCoursePost.setHeader("Referer", mainUrl + stuNumber);        UrlEncodedFormEntity entitySource = new UrlEncodedFormEntity(                stuCoursePair);        queryStuCoursePost.setEntity(entitySource);                HttpResponse responseStuCourse = client.execute(queryStuCoursePost);        String html = IOUtils.getHtml(responseStuCourse.getEntity()                .getContent(), "GB2312");        Document docCourse = Jsoup.parse(html);        Elements eleCourse = docCourse.select("td");                HashMap<String, ArrayList<String>>hashMap=new HashMap<String, ArrayList<String>>();        System.out.println("eleCourse.size()"+eleCourse.size()+""); //测试代码       //        for (Element element : eleCourse) {//System.out.println(element.text());//}
     以上是获取课程表的源码,后面的有些没有放上去,原因是每个学校所得出结果都有所不同,所以你们自己根据自己学校进行数据的封装吧,这里就不一一叙说了,因为

解析课程表的信息真的很坑,我不知是不是每个学校的数据都这样,我觉得吧,还是你们亲自动手会比较好。

     这次的博客就先这样把,本人第一次写实战类的博客,觉得写的不怎么好,望见谅。这里不贴出大量的代码是因为本人觉得其实原理都差不多,如果你看了上一篇的博客你就知道究竟是怎么回事。再者因为本人研究了java爬虫两个星期,觉得把,还是自己动手起来效果会好很多,所以打算贴出一些重要的代码,其他的让你们自行补充。

     望提点建议,本人将来还会打算写一篇基于人脸识别的签到系统,所以希望能写好点。

    今天就到此为止把。

       

0 0
原创粉丝点击