zoukankan      html  css  js  c++  java
  • HttpClient + Jsoup模拟登录教务处并获取课表

      

    1、概述

      最近想做一个校园助手类的APP,由于第一次做,所以打算先把每个功能单独实现,防止乱了阵脚。利用教务处登录获取课表和成绩等是一个基本功能,所以以获取课表为例实现了这个功能。完整代码点这里,尝试了好几次的,所以写的比较乱

    2、涉及的关键知识

      首先,明确获取课表的流程:其实,获取课表就是让手机模拟浏览器,给服务器传去账号、密码,然后服务器会返回cookies(不懂自行百度),利用cookie就可以穿梭自如了,比如查课表。但是,浏览器登录时,返回的html文件浏览器是会自动解析成网页展现在我们面前的,但是APP就不行了,所以需要我们自己从html字符流中解析出我们需要的信息。就我自己的情况来看,模拟登录花了不少时间(这方面很不熟),解析html很快就解决了(可能是之前实践偶解析JSON)。

      这样一个APP主要涉及到3个重要知识点:

    1、如何模拟登录:java有自己的HttpURLConnection,但是不够灵活,所以用 apache的HttpClient更方便

    2、如何解析HTML:网上查一下,Jsoup很合适。

    3、AsyncTask:显然获取网页并解析是不能再主线程进行的,所以需要使用异步任务。

    4、回调函数:这个不是必须的,但是我为了降低程序耦合度把网络请求那部分单独成了一个类,这时候更新主UI就需要利用回调函数了,之后细说

    3、模拟登陆(以窝工UPR为例)

      1、解析教务处登录界面,看到一些教程用的还是HttpWatch,确实过时了,显然直接Google浏览器F12就行了。如下图,选择Network

      点一下登录,就可以看到一大堆信息,我们需要的是第一个:

      点击就可以看到详细信息了:

      重要的有两个,Cookie,拿到这个我们才能导出去访问,Form Data就是模拟登录时要提交(POST)的表单数据;

    4、HTML解析

    利用上一步模拟登录拿到的Cookie就可以去获取课表了,同理,需要解析网页,如下,点击我的课表

      可以看到一大堆信息,找到需要的

      这个Response就是会返回我们的字符流,我们需要的就是解析它,设计到Jsoup的详细使用就不细说了,自己也是今天才接触,

      总之借助以上两步就可以写出主要类Login.java的代码了,如下:

      1 package com.example.upr.net;
      2 
      3 import java.io.BufferedReader;
      4 import java.io.IOException;
      5 import java.io.InputStream;
      6 import java.io.InputStreamReader;
      7 import java.io.UnsupportedEncodingException;
      8 import java.util.ArrayList;
      9 import java.util.List;
     10 
     11 import org.apache.http.HttpEntity;
     12 import org.apache.http.HttpResponse;
     13 import org.apache.http.NameValuePair;
     14 import org.apache.http.client.ClientProtocolException;
     15 import org.apache.http.client.HttpClient;
     16 import org.apache.http.client.entity.UrlEncodedFormEntity;
     17 import org.apache.http.client.methods.HttpGet;
     18 import org.apache.http.client.methods.HttpPost;
     19 import org.apache.http.cookie.Cookie;
     20 import org.apache.http.impl.client.AbstractHttpClient;
     21 import org.apache.http.impl.client.DefaultHttpClient;
     22 import org.apache.http.message.BasicNameValuePair;
     23 import org.jsoup.Jsoup;
     24 import org.jsoup.nodes.Document;
     25 import org.jsoup.nodes.Element;
     26 import org.jsoup.select.Elements;
     27 
     28 import com.example.upr.CompleteListener;
     29 
     30 import android.R.integer;
     31 import android.os.AsyncTask;
     32 import android.provider.ContactsContract.Contacts.Data;
     33 import android.util.Log;
     34 import android.widget.Toast;
     35 
     36 public class Login extends AsyncTask<Void, Void, String[][]>{
     37 
     38     private String zjh;
     39     private String mm;
     40     private String webPage;
     41     private String [][] kebiao = new String[15][8];
     42     private CompleteListener listener;
     43     public Login(String account, String password, CompleteListener listener) {
     44         zjh = account;
     45         mm = password;
     46 
     47         this.listener = listener;
     48     }
     49     @Override
     50     protected String[][] doInBackground(Void... arg0) {
     51         List<NameValuePair> list = new ArrayList<NameValuePair>();
     52         list.add(new BasicNameValuePair("zjh", zjh));
     53         list.add(new BasicNameValuePair("mm", mm));//表单信息
     54         String encode = "gb2312";//编码格式,从F12工具中可以找到
     55         HttpClient httpClient = new DefaultHttpClient();
     56         List<Cookie> cookies;
     57         try {
     58             HttpEntity entity = new UrlEncodedFormEntity(list ,encode);//封装数据
     59             HttpPost post = new HttpPost(com.example.upr.Constant.LOGIN_URL);//建立POST请求
     60             post.setEntity(entity);
     61             HttpResponse httpResponse = httpClient.execute(post);
     62             String data, result;
     63             if (httpResponse.getStatusLine().getStatusCode() == 200) {//登录成功
     64                 cookies = ((AbstractHttpClient) httpClient).getCookieStore().getCookies();//获取Cookie
     65                 HttpGet httpGet = new HttpGet("http://zhjw.dlut.edu.cn/xkAction.do?actionType=6");
     66                 httpGet.setHeader("Cookie", "JSESSIONID="+ cookies.get(0).getValue()+";"+
     67                         "NSC_kjbpxv-iuuq="+cookies.get(1).getValue());//注意分号
     68                 httpResponse = new DefaultHttpClient().execute(httpGet);
     69                 
     70                 StringBuffer sb = new StringBuffer();
     71                 entity = httpResponse.getEntity();
     72                 InputStream inputStream = entity.getContent();
     73                 BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, encode));
     74                 while ((data = br.readLine()) != null) {  
     75                     sb.append(data);  //读取返回的网页
     76                 }  
     77                 result = sb.toString();
     78                 webPage = result;
     79         
     80             } else {
     81                 return null;
     82             }
     83         } catch (UnsupportedEncodingException e) {
     84             e.printStackTrace();
     85             return null;
     86         } catch (ClientProtocolException e) {
     87             // TODO Auto-generated catch block
     88             e.printStackTrace();
     89             return null;
     90         } catch (IOException e) {
     91             // TODO Auto-generated catch block
     92             e.printStackTrace();
     93             return null;
     94         }
     95         
     96         Document document = Jsoup.parse(webPage);
     97         if (document != null) {
     98             Element element = document.getElementById("user");//通过id直接定位到数据
     99             Elements trElements = element.select("tr");
    100             //以下是提取课表信息,每个网站不同,一下代码要解析的html放在最下面了
    101             for (int i = 0; i < trElements.size(); i++) {
    102                 Elements tdElements = trElements.get(i).select("td");
    103                 for (int j = 0; j < tdElements.size(); j++) {
    104                     String text = tdElements.get(j).text();
    105                     if (tdElements.size() == 1) {
    106                         continue;
    107                     } else if (tdElements.size()==9) {
    108                         if (j != 0) {
    109                             kebiao[i][j-1] = text;
    110                         }
    111                     }else {
    112                         kebiao[i][j] = text;
    113                     }
    114                     
    115                 }
    116             }
    117             return kebiao;
    118         } else {
    119             return null;
    120         }
    121 
    122     }
    123     @Override
    124     protected void onPostExecute(String[][] result) {
    125         super.onPostExecute(result);
    126         listener.onConnectFinish(result);//执行回调函数,更新主UI
    127     }
    128 }
    129 /*
    130 <table cellpadding="0" width="100%" class="displayTag" cellspacing="0" border="1" id="user">
    131             <tr>
    132               <td colspan="2" class="sortable">&nbsp;</td>
    133               <td width="13%" class="sortable">
    134                 <div align="center">星期一</div></td>
    135               <td width="13%" class="sortable">
    136                 <div align="center">星期二</div></td>
    137               <td width="13%" class="sortable">
    138                 <div align="center">星期三</div></td>
    139               <td width="13%" class="sortable">
    140                 <div align="center">星期四</div></td>
    141               <td width="13%" class="sortable">
    142                 <div align="center">星期五</div></td>
    143               <td width="13%" class="sortable">
    144                 <div align="center">星期六</div></td>
    145               <td width="13%" class="sortable">
    146                 <div align="center">星期日</div></td>
    147             </tr>
    148             <tr bgcolor="#FFFFFF">
    149               <td width="3%" rowspan="4">&nbsp;
    150                 <p class="style4">上午</p></td>
    151               <td width="11%">第1节(08:00-08:45)</td>
    152               <td>&nbsp; 计算机网络A_01(西部校区综合教学2号楼B406)
    153                 <br></td>
    154               <td>&nbsp; &nbsp;</td>
    155               <td>&nbsp; &nbsp;</td>
    156               <td>&nbsp; 编译原理_01(校部综合教学1号楼综151)
    157                 <br></td>
    158               <td>&nbsp; 计算机组成原理_01(西部校区综合教学2号楼B103)
    159                 <br></td>
    160               <td>&nbsp; &nbsp;</td>
    161               <td>&nbsp; &nbsp;</td></tr>
    162             <tr bgcolor="#FFFFFF">
    163               <td width="11%">第2节(08:50-09:35)</td>
    164               <td>&nbsp; 计算机网络A_01(西部校区综合教学2号楼B406)
    165                 <br></td>
    166               <td>&nbsp; &nbsp;</td>
    167               <td>&nbsp; &nbsp;</td>
    168               <td>&nbsp; 编译原理_01(校部综合教学1号楼综151)
    169                 <br></td>
    170               <td>&nbsp; 计算机组成原理_01(西部校区综合教学2号楼B103)
    171                 <br></td>
    172               <td>&nbsp; &nbsp;</td>
    173               <td>&nbsp; &nbsp;</td></tr>
    174             <tr bgcolor="#FFFFFF">
    175               <td width="11%">第3节(10:05-10:50)</td>
    176               <td>&nbsp; &nbsp;</td>
    177               <td>&nbsp; 面向对象程序设计_01(西部校区综合教学2号楼A301)
    178                 <br></td>
    179               <td>&nbsp; &nbsp;</td>
    180               <td>&nbsp; 人工智能_01(西部校区综合教学2号楼A101)
    181                 <br></td>
    182               <td>&nbsp; &nbsp;</td>
    183               <td>&nbsp; &nbsp;</td>
    184               <td>&nbsp; &nbsp;</td></tr>
    185             <tr bgcolor="#FFFFFF">
    186               <td width="11%">第4节(10:55-11:40)</td>
    187               <td>&nbsp; &nbsp;</td>
    188               <td>&nbsp; 面向对象程序设计_01(西部校区综合教学2号楼A301)
    189                 <br></td>
    190               <td>&nbsp; &nbsp;</td>
    191               <td>&nbsp; 人工智能_01(西部校区综合教学2号楼A101)
    192                 <br></td>
    193               <td>&nbsp; &nbsp;</td>
    194               <td>&nbsp; &nbsp;</td>
    195               <td>&nbsp; &nbsp;</td>
    196               <tr bgcolor="#FFFFFF">
    197                 <td colspan="9">&nbsp;
    198                   <p align="center" class="td2 style5">
    199                     <strong>午 休</strong></p>
    200                 </td>
    201               </tr>
    202             </tr>
    203             <tr bgcolor="#FFFFFF">
    204               <td width="3%" rowspan="4">&nbsp;
    205                 <p class="style4">下午</p></td>
    206               <td width="11%">第5节(13:30-14:15)</td>
    207               <td>&nbsp; 编译原理_01(校部综合教学1号楼综151)
    208                 <br></td>
    209               <td>&nbsp; 计算机组成原理_01(西部校区综合教学2号楼B103)
    210                 <br></td>
    211               <td>&nbsp; &nbsp;</td>
    212               <td>&nbsp; 计算机网络A_01(西部校区综合教学2号楼B406)
    213                 <br></td>
    214               <td>&nbsp; &nbsp;</td>
    215               <td>&nbsp; &nbsp;</td>
    216               <td>&nbsp; &nbsp;</td></tr>
    217             <tr bgcolor="#FFFFFF">
    218               <td width="11%">第6节(14:20-15:05)</td>
    219               <td>&nbsp; 编译原理_01(校部综合教学1号楼综151)
    220                 <br></td>
    221               <td>&nbsp; 计算机组成原理_01(西部校区综合教学2号楼B103)
    222                 <br></td>
    223               <td>&nbsp; &nbsp;</td>
    224               <td>&nbsp; 计算机网络A_01(西部校区综合教学2号楼B406)
    225                 <br></td>
    226               <td>&nbsp; &nbsp;</td>
    227               <td>&nbsp; &nbsp;</td>
    228               <td>&nbsp; &nbsp;</td></tr>
    229             <tr bgcolor="#FFFFFF">
    230               <td width="11%">第7节(15:35-16:20)</td>
    231               <td>&nbsp; 人工智能_01(西部校区综合教学2号楼A101)
    232                 <br></td>
    233               <td>&nbsp; &nbsp;</td>
    234               <td>&nbsp; &nbsp;</td>
    235               <td>&nbsp; &nbsp;</td>
    236               <td>&nbsp; 面向对象程序设计_01(西部校区综合教学2号楼A301)
    237                 <br></td>
    238               <td>&nbsp; &nbsp;</td>
    239               <td>&nbsp; &nbsp;</td></tr>
    240             <tr bgcolor="#FFFFFF">
    241               <td width="11%">第8节(16:25-17:10)</td>
    242               <td>&nbsp; 人工智能_01(西部校区综合教学2号楼A101)
    243                 <br></td>
    244               <td>&nbsp; &nbsp;</td>
    245               <td>&nbsp; &nbsp;</td>
    246               <td>&nbsp; &nbsp;</td>
    247               <td>&nbsp; 面向对象程序设计_01(西部校区综合教学2号楼A301)
    248                 <br></td>
    249               <td>&nbsp; &nbsp;</td>
    250               <td>&nbsp; &nbsp;</td>
    251               <tr bgcolor="#FFFFFF">
    252                 <td colspan="9">&nbsp;
    253                   <p align="center" class="td2 style5">
    254                     <strong>晚 饭</strong></p>
    255                 </td>
    256               </tr>
    257             </tr>
    258             <tr bgcolor="#FFFFFF">
    259               <td width="3%" rowspan="4">&nbsp;
    260                 <p class="style4">晚上</p></td>
    261               <td width="11%">第9节(18:00-18:45)</td>
    262               <td>&nbsp; 社会学*_886(校部综合教学1号楼综152)
    263                 <br></td>
    264               <td>&nbsp; 人类文明史*_887(校部材料馆材101)
    265                 <br></td>
    266               <td>&nbsp; &nbsp;</td>
    267               <td>&nbsp; &nbsp;</td>
    268               <td>&nbsp; &nbsp;</td>
    269               <td>&nbsp; &nbsp;</td>
    270               <td>&nbsp; &nbsp;</td></tr>
    271             <tr bgcolor="#FFFFFF">
    272               <td width="11%">第10节(18:55-19:40)</td>
    273               <td>&nbsp; 社会学*_886(校部综合教学1号楼综152)
    274                 <br></td>
    275               <td>&nbsp; 人类文明史*_887(校部材料馆材101)
    276                 <br></td>
    277               <td>&nbsp; &nbsp;</td>
    278               <td>&nbsp; &nbsp;</td>
    279               <td>&nbsp; &nbsp;</td>
    280               <td>&nbsp; &nbsp;</td>
    281               <td>&nbsp; &nbsp;</td></tr>
    282             <tr bgcolor="#FFFFFF">
    283               <td width="11%">第11节(19:50-20:35)</td>
    284               <td>&nbsp; 社会学*_886(校部综合教学1号楼综152)
    285                 <br></td>
    286               <td>&nbsp; 人类文明史*_887(校部材料馆材101)
    287                 <br></td>
    288               <td>&nbsp; &nbsp;</td>
    289               <td>&nbsp; &nbsp;</td>
    290               <td>&nbsp; &nbsp;</td>
    291               <td>&nbsp; &nbsp;</td>
    292               <td>&nbsp; &nbsp;</td></tr>
    293             <tr bgcolor="#FFFFFF">
    294               <td width="11%">第12节(20:45-21:30)</td>
    295               <td>&nbsp; &nbsp;</td>
    296               <td>&nbsp; &nbsp;</td>
    297               <td>&nbsp; &nbsp;</td>
    298               <td>&nbsp; &nbsp;</td>
    299               <td>&nbsp; &nbsp;</td>
    300               <td>&nbsp; &nbsp;</td>
    301               <td>&nbsp; &nbsp;</td></tr>
    302           </table>
    303 
    304 */
    View Code

    5、关于回调函数的使用

      这一部分之前完全没预料到,只是后来才发现,不用内部类,想更新UI就得用回调函数,其更深层次的思想是一种设计模式,还是自己学的太少!知识使用完全浮于表面。

    6、Demo演示

    7、总结

      零零散散花了不少时间,一来确实第一次做类似工作,二来自己习惯非常不好,对于新工具,研究API和即学即用能力不强。明天应该好好研究一下HttpClientJsoup,达到熟练抓取各种网页的目的!毕竟这只是开始!现在的学习状态实在太低效了。

      以上。

  • 相关阅读:
    Scala Ant Tasks
    Git挂钩
    读写文件
    DC10用CSS定位控制网页布局
    table设置colspan属性,列宽显示错位解决方法
    ATM和购物商城-错题集
    python 函数参数多种传递方法
    python 函数 初学
    python 集合 gather
    元组 字体高亮 购物车练习
  • 原文地址:https://www.cnblogs.com/zhaoyu1995/p/5875577.html
Copyright © 2011-2022 走看看