• 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,达到熟练抓取各种网页的目的!毕竟这只是开始!现在的学习状态实在太低效了。

      以上。

  • 相关阅读:
    苹果一体机发射Wi-Fi
    iphone 屏蔽系统自动更新,消除设置上的小红点
    data parameter is nil 异常处理
    copy与mutableCopy的区别总结
    java axis2 webservice
    mysql 远程 ip访问
    mysql 存储过程小问题
    mysql游标错误
    is not writable or has an invalid setter method错误的解决
    Struts2中关于"There is no Action mapped for namespace / and action name"的总结
  • 原文地址:https://www.cnblogs.com/zhaoyu1995/p/5875577.html
Copyright © 2020-2023  润新知