HttpClient+Jsoup模拟登陆,解析HTML,信息筛选(广工图书馆)

最近在做一个校园综合Android客户端,主要是想把学校各类网站信息进行整合,放在一个平台上,供学校学生阅览。

 

思路如下:

 

拿广东工业大学图书馆网站作为一个例子

实现目标:用个人账号登陆图书馆并获取到个人借阅情况。

登陆地址 http://222.200.98.171:81/login.aspx

这里会用到Chrome的开发者工具(浏览器按F12可以开启)



 
 

打开登陆界面的源码,下面是源码中的form标签

 

Html代码 

      < li>
                //                  //      
                              登录我的图书馆      
                                                                                                                        图书证号:                                                        请输入证号                                                
                                                    密        码:                                                        请输入密码                                                
                      
                                                
                                                                                                
                  
              
          
                      
          1.  如果您使用的是公共电脑,请在使用完毕后,务必退出登录,以保安全。          2.  首次登录,请先修改初始密码。          
                                            
      //        //          //      

 

里面很多代码,我们要从中提取出我们登陆所需要的表单信息,input 和 select 这些标签都是作为登陆表单内容,这里只有input标签我们就提取它就好了,代码如下:

initLoginParmas(String userName,StringpassWord)和getLoginFormData(String url)两个方法

Java代码 

  1. /** 
  2.      * 初始化参数 
  3.      *  
  4.      * @param userName 
  5.      * @param passWord 
  6.      * @return 
  7.      * @throws ParseException 
  8.      * @throws IOException 
  9.      */  
  10.     public static List initLoginParmas(String userName,  
  11.             String passWord) throws ParseException, IOException {  
  12.         List parmasList = new ArrayList();  
  13.         HashMap parmasMap = getLoginFormData(LoginUrl);  
  14.         Set keySet = parmasMap.keySet();  
  15.   
  16.         for (String temp : keySet) {  
  17.             if (temp.contains("Username")) {  
  18.                 parmasMap.put(temp, userName);  
  19.             } else if (temp.contains("txtPas")) {  
  20.                 parmasMap.put(temp, passWord);  
  21.             }  
  22.         }  
  23.   
  24.         Set keySet2 = parmasMap.keySet();  
  25.         System.out.println("表单内容:");  
  26.         for (String temp : keySet2) {  
  27.             System.out.println(temp + " = " + parmasMap.get(temp));  
  28.         }  
  29.         for (String temp : keySet2) {  
  30.             parmasList.add(new BasicNameValuePair(temp, parmasMap.get(temp)));  
  31.         }  
  32.   
  33.         // System.out.println("initParams \n" + parmasMap);  
  34.   
  35.         return parmasList;  
  36.   
  37.     }  

Java代码 

  1. /** 
  2.      * 获取登录表单input内容 
  3.      *  
  4.      * @param url 
  5.      * @return 
  6.      * @throws IOException 
  7.      * @throws ParseException 
  8.      */  
  9.     public static HashMap getLoginFormData(String url)  
  10.             throws ParseException, IOException {  
  11.         Document document = Jsoup.parse(getHtml(url));  
  12.         Elements element1 = document.getElementsByTag("form");// 找出所有form表单  
  13.         Element element = element1.select("[method=post]").first();// 筛选出提交方法为post的表单  
  14.         Elements elements = element.select("input[name]");// 把表单中带有name属性的input标签取出  
  15.         HashMap parmas = new HashMap();  
  16.         for (Element temp : elements) {  
  17.             parmas.put(temp.attr("name"), temp.attr("value"));// 把所有取出的input,取出其name,放入Map中  
  18.         }  
  19.         return parmas;  
  20.     }  

 

最后表单结果是:

表单内容:

Java代码 

  1. ctl00$ContentPlaceHolder1$txtlogintype = 0  
  2. __VIEWSTATE = /wEPDwULLTE0MjY3MDAxNzcPZBYCZg9kFgoCAQ8PFgIeCEltYWdlVXJsBRt+XGltYWdlc1xoZWFkZXJvcGFjNGdpZi5naWZkZAICDw8WAh4EVGV4dAUt5bm/5Lic5bel5Lia5aSn5a2m5Zu+5Lmm6aaG5Lmm55uu5qOA57Si57O757ufZGQCAw8PFgIfAQUcMjAxM+W5tDAz5pyIMD
  3. ctl00$ContentPlaceHolder1$txtPas_Lib =密码不告诉你  
  4. __EVENTVALIDATION = /wEWBQKa7ezdCwKOmK5RApX9wcYGAsP9wL8JAqW86pcIaBhXmFYzd5pGDTk/afln2TfArPw=  
  5. ctl00$ContentPlaceHolder1$txtUsername_Lib = 3110006527  
  6. ctl00$ContentPlaceHolder1$btnLogin_Lib = 登录  

 

 

接下来是要登陆获取权限也就是获取到Cookie

代码如下:

Java代码 

  1. /** 
  2.      * 图书馆登陆 
  3.      *  
  4.      * @param context 
  5.      * @return 返回登陆后的界面Html代码 
  6.      * @throws ClientProtocolException 
  7.      * @throws IOException 
  8.      */  
  9.     public static String login() throws ClientProtocolException, IOException {  
  10.         List parmasList = new ArrayList();  
  11.         parmasList = initLoginParmas("3110006527", "2787457");  
  12.         HttpPost post = new HttpPost(LoginUrl);  
  13.         post.getParams().setParameter(ClientPNames.HANDLE_REDIRECTS, false);  
  14.         // 阻止自动重定向,目的是获取第一个ResponseHeader的Cookie和Location  
  15.         post.setHeader("Content-Type",  
  16.                 "application/x-www-form-urlencoded;charset=gbk");  
  17.         // 设置编码为GBK  
  18.         post.setEntity(new UrlEncodedFormEntity(parmasList, "GBK"));  
  19.         HttpResponse response = new DefaultHttpClient().execute(post);  
  20.         cookie = response.getFirstHeader("Set-Cookie").getValue();  
  21.         // 取得cookie并保存起来  
  22.         // System.out.println("cookie= " + cookie);  
  23.         location = response.getFirstHeader("Location").getValue();  
  24.         // 重定向地址,目的是连接到主页  
  25.         mainUrl = Host + location;  
  26.         // 构建主页地址  
  27.         String html = getHtml(mainUrl);  
  28.         return html;  
  29.   
  30.     }  

 

登陆获取Cookie时候会遇到返回状态码是302,这个时候Post方法的话,系统会自动重定向到Location地址,这时候你看到的ResponseHeader已经不是你登陆后返回的那个了,而是你访问重定向地址时候返回的ResponseHeader,而cookie是含在登陆时候返回的ResponseHeader里面所以特别要注意添加语句

Java代码 

  1. post.getParams().setParameter(ClientPNames.HANDLE_REDIRECTS,false);  

 

 

给Post设置参数,这样就会阻止重定向,从而可以获取Cookie和Location(为了访问主页界面)

Java代码 

  1. cookie =response.getFirstHeader("Set-Cookie").getValue();  

 

 

接下来需要做的是根据Location得到主页地址,用Jsoup去解析主页,分析出我的借书情况的页面地址

接下来我们访问其他网页的时候就需要用到cookie 了,所以在用post或者get方法的时候要调用addHeader()或者setHeader();把Cookie设置进去

Java代码 

  1. /** 
  2.  * 获取网页HTML源代码 
  3.  *  
  4.  * @param url 
  5.  * @return 
  6.  * @throws ParseException 
  7.  * @throws IOException 
  8.  */  
  9.   
  10. private static String getHtml(String url) throws ParseException,  
  11.         IOException {  
  12.     // TODO Auto-generated method stub  
  13.     HttpGet get = new HttpGet(url);  
  14.     if ("" != cookie) {  
  15.         get.addHeader("Cookie", cookie);  
  16.     }  
  17.     HttpResponse httpResponse = new DefaultHttpClient().execute(get);  
  18.     HttpEntity entity = httpResponse.getEntity();  
  19.     return EntityUtils.toString(entity);  
  20. }  

 

通过Chrome浏览器分析页面源码,可以看到该标签

Java代码 

  1. 当前借阅情况和续借  

bookborrowed.aspx  这一段就是我们需要的

 

获取代码如下:

Java代码 

  1. public static void getMyBorrowedBooks() {  
  2.         try {  
  3.             Document document = Jsoup.parse(login());  
  4.             Elements elements1 = document  
  5.                     .getElementsContainingOwnText("当前借阅情况和续借");// 通过text关键字找到所要的标签  
  6.             String url = elements1.first().attr("href");  
  7.             borrowedBooksUrl = mainUrl.substring(0,  
  8.                     mainUrl.lastIndexOf("/") + 1) + url;// 取值和mainUrl进行拼凑组织借阅情况地址  
  9.             getBookBorrowedData(getHtml(borrowedBooksUrl));  
  10.   
  11.         } catch (IOException e) {  
  12.             // TODO Auto-generated catch block  
  13.             e.printStackTrace();  
  14.         }  
  15.     }  

 

 

       获取到借书情况的地址后,我们就去访问这个地址,获取源码。

我们所需要的事这部分的数据(只截取一部分):

Java代码 

  1.               
  2.              
  3.              
  4.              
  5.            续满  
  6.              
  7.              
  8.              
  9.            2013-04-10  
  10.            编写高质量代码 [专著]:改善Java程序的151个建议=Writing solw Java cove:151 suggestons to improve your Java program/秦小波著  
  11.               
  12.            中文图书  
  13.            A2973844  
  14.            2012-12-05  
  15.           
  16.          
  17.                 

 

 

    通过下面代码  用Jsoup进行筛选         

Java代码 

  1. /** 
  2.      * 获取借书情况具体数据(List) 
  3.      *  
  4.      * @param src 
  5.      * @return List 
  6.      */  
  7.     private static List getBookBorrowedData(String src) {  
  8.         List data = new ArrayList();  
  9.         Document document = Jsoup.parse(src);  
  10.         Element element = document.select("[id=borrowedcontent]").first()  
  11.                 .getElementsByTag("table").first();  
  12.         Elements elements2 = element.getElementsByTag("tr");  
  13.         for (Element temp2 : elements2) {  
  14.             Elements elements3 = temp2.getElementsByTag("td");  
  15.             BookEntity entity = new test().new BookEntity()  
  16.                     .setIsFullData(elements3.get(0).text())  
  17.                     .setData2Return(elements3.get(1).text())  
  18.                     .setName(elements3.get(2).text())  
  19.                     .setData2Borrowed(elements3.get(6).text());  
  20.             data.add(entity);  
  21.   
  22.         }  
  23.         data.remove(0);  
  24.         System.out.println("借书情况\n");  
  25.   
  26.         for (BookEntity temp : data) {  
  27.             System.out.println(temp.getName() + "\n" + temp.getData2Borrowed()  
  28.                     + "\n" + temp.getData2Return() + "\n"  
  29.                     + temp.getIsFullData());  
  30.         }  
  31.         return data;  
  32.   
  33.     }  

 

 

    最后打印出来结果是:

Java代码 

  1. 借书情况  
  2.   
  3. 编写高质量代码 [专著]:改善Java程序的151个建议=Writing solw Java cove:151 suggestons to improve your Java program/秦小波著  
  4. 2012-12-05  
  5. 2013-04-10  
  6. 续满  
  7. 疯狂Java [专著]:突破程序员基本功的16课/李刚编著  
  8. 2012-12-05  
  9. 2013-04-10  
  10. 续满  
  11. 程序员修炼之道 [专著]:从小工到专家=The pragmatic programmer:From journeyman to master:评注版/(美)Andrew Hunt,(美)David Thomas著;周爱民,蔡学镛评注  
  12. 2012-11-22  
  13. 2013-04-10  
  14. 续满  
  15. 重构:改善既有代码的设计=Refactoring:improving the design of existing code/(美)Martin Fowler著;熊节译  
  16. 2012-11-22  
  17. 2013-04-10  
  18. 续满  
  19. Android高薪之路 [专著]:Android程序员面试宝典/李宁编著  
  20. 2012-11-29  
  21. 2013-04-10  
  22. 续满  
  23. Android技术内幕 [专著]·系统卷=Android internals·System/杨丰盛著  
  24. 2012-12-04  
  25. 2013-04-10  
  26. 续满  
  27. 我编程, 我快乐 [专著]:程序员职业规划之道=The passionate programmer:creating a remarkable career in software development/(美) Chad Fowler著;于梦瑄译  
  28. 2013-01-17  
  29. 2013-04-17  
  30. 续满  

Java代码 

  1. 完整代码:  
  2. package moniLogin;  
  3.   
  4. import java.io.IOException;  
  5. import java.util.ArrayList;  
  6. import java.util.HashMap;  
  7. import java.util.Iterator;  
  8. import java.util.List;  
  9. import java.util.Set;  
  10.   
  11. import org.apache.http.Header;  
  12. import org.apache.http.HeaderElement;  
  13. import org.apache.http.HttpEntity;  
  14. import org.apache.http.HttpResponse;  
  15. import org.apache.http.NameValuePair;  
  16. import org.apache.http.ParseException;  
  17. import org.apache.http.client.ClientProtocolException;  
  18. import org.apache.http.client.entity.UrlEncodedFormEntity;  
  19. import org.apache.http.client.methods.HttpGet;  
  20. import org.apache.http.client.methods.HttpPost;  
  21. import org.apache.http.client.params.ClientPNames;  
  22. import org.apache.http.impl.client.DefaultHttpClient;  
  23. import org.apache.http.message.BasicNameValuePair;  
  24. import org.apache.http.util.EntityUtils;  
  25. import org.jsoup.Jsoup;  
  26. import org.jsoup.nodes.Document;  
  27. import org.jsoup.nodes.Element;  
  28. import org.jsoup.select.Elements;  
  29.   
  30. public class test {  
  31.     private static String LoginUrl = "http://222.200.98.171:81/login.aspx";  
  32.     private static String Host = "http://222.200.98.171:81";  
  33.     private static String mainUrl = "";  
  34.     private static String borrowedBooksUrl = "";  
  35.     private static String cookie = "";  
  36.     private static String location = "";  
  37.   
  38.     /** 
  39.      * @param args 
  40.      */  
  41.     public static void main(String[] args) {  
  42.         // TODO Auto-generated method stub  
  43.         getMyBorrowedBooks();  
  44.     }  
  45.   
  46.     public static void getMyBorrowedBooks() {  
  47.         try {  
  48.             Document document = Jsoup.parse(login());  
  49.             Elements elements1 = document  
  50.                     .getElementsContainingOwnText("当前借阅情况和续借");// 通过text关键字找到所要的标签  
  51.             String url = elements1.first().attr("href");  
  52.             borrowedBooksUrl = mainUrl.substring(0,  
  53.                     mainUrl.lastIndexOf("/") + 1) + url;// 取值和mainUrl进行拼凑组织借阅情况地址  
  54.             getBookBorrowedData(getHtml(borrowedBooksUrl));  
  55.   
  56.         } catch (IOException e) {  
  57.             // TODO Auto-generated catch block  
  58.             e.printStackTrace();  
  59.         }  
  60.     }  
  61.   
  62.     /** 
  63.      * 获取借书情况具体数据(List) 
  64.      *  
  65.      * @param src 
  66.      * @return List 
  67.      */  
  68.     private static List getBookBorrowedData(String src) {  
  69.         List data = new ArrayList();  
  70.         Document document = Jsoup.parse(src);  
  71.         Element element = document.select("[id=borrowedcontent]").first()  
  72.                 .getElementsByTag("table").first();  
  73.         Elements elements2 = element.getElementsByTag("tr");  
  74.         for (Element temp2 : elements2) {  
  75.             Elements elements3 = temp2.getElementsByTag("td");  
  76.             BookEntity entity = new test().new BookEntity()  
  77.                     .setIsFullData(elements3.get(0).text())  
  78.                     .setData2Return(elements3.get(1).text())  
  79.                     .setName(elements3.get(2).text())  
  80.                     .setData2Borrowed(elements3.get(6).text());  
  81.             data.add(entity);  
  82.   
  83.         }  
  84.         data.remove(0);  
  85.         System.out.println("借书情况\n");  
  86.   
  87.         for (BookEntity temp : data) {  
  88.             System.out.println(temp.getName() + "\n" + temp.getData2Borrowed()  
  89.                     + "\n" + temp.getData2Return() + "\n"  
  90.                     + temp.getIsFullData());  
  91.         }  
  92.         return data;  
  93.   
  94.     }  
  95.   
  96.     /** 
  97.      * 图书馆登陆 
  98.      *  
  99.      * @param context 
  100.      * @return 返回登陆后的界面Html代码 
  101.      * @throws ClientProtocolException 
  102.      * @throws IOException 
  103.      */  
  104.     public static String login() throws ClientProtocolException, IOException {  
  105.         List parmasList = new ArrayList();  
  106.         parmasList = initLoginParmas("3110006527", "密码不告诉你");  
  107.         HttpPost post = new HttpPost(LoginUrl);  
  108.         post.getParams().setParameter(ClientPNames.HANDLE_REDIRECTS, false);  
  109.         // 阻止自动重定向,目的是获取第一个ResponseHeader的Cookie和Location  
  110.         post.setHeader("Content-Type",  
  111.                 "application/x-www-form-urlencoded;charset=gbk");  
  112.         // 设置编码为GBK  
  113.         post.setEntity(new UrlEncodedFormEntity(parmasList, "GBK"));  
  114.         HttpResponse response = new DefaultHttpClient().execute(post);  
  115.         cookie = response.getFirstHeader("Set-Cookie").getValue();  
  116.         // 取得cookie并保存起来  
  117.         // System.out.println("cookie= " + cookie);  
  118.         location = response.getFirstHeader("Location").getValue();  
  119.         // 重定向地址,目的是连接到主页  
  120.         mainUrl = Host + location;  
  121.         // 构建主页地址  
  122.         String html = getHtml(mainUrl);  
  123.         return html;  
  124.   
  125.     }  
  126.   
  127.     /** 
  128.      * 获取网页HTML源代码 
  129.      *  
  130.      * @param url 
  131.      * @return 
  132.      * @throws ParseException 
  133.      * @throws IOException 
  134.      */  
  135.   
  136.     private static String getHtml(String url) throws ParseException,  
  137.             IOException {  
  138.         // TODO Auto-generated method stub  
  139.         HttpGet get = new HttpGet(url);  
  140.         if ("" != cookie) {  
  141.             get.addHeader("Cookie", cookie);  
  142.         }  
  143.         HttpResponse httpResponse = new DefaultHttpClient().execute(get);  
  144.         HttpEntity entity = httpResponse.getEntity();  
  145.         return EntityUtils.toString(entity);  
  146.     }  
  147.   
  148.     /** 
  149.      * 初始化参数 
  150.      *  
  151.      * @param userName 
  152.      * @param passWord 
  153.      * @return 
  154.      * @throws ParseException 
  155.      * @throws IOException 
  156.      */  
  157.     public static List initLoginParmas(String userName,  
  158.             String passWord) throws ParseException, IOException {  
  159.         List parmasList = new ArrayList();  
  160.         HashMap parmasMap = getLoginFormData(LoginUrl);  
  161.         Set keySet = parmasMap.keySet();  
  162.   
  163.         for (String temp : keySet) {  
  164.             if (temp.contains("Username")) {  
  165.                 parmasMap.put(temp, userName);  
  166.             } else if (temp.contains("txtPas")) {  
  167.                 parmasMap.put(temp, passWord);  
  168.             }  
  169.         }  
  170.   
  171.         Set keySet2 = parmasMap.keySet();  
  172.         System.out.println("表单内容:");  
  173.         for (String temp : keySet2) {  
  174.             System.out.println(temp + " = " + parmasMap.get(temp));  
  175.         }  
  176.         for (String temp : keySet2) {  
  177.             parmasList.add(new BasicNameValuePair(temp, parmasMap.get(temp)));  
  178.         }  
  179.   
  180.         // System.out.println("initParams \n" + parmasMap);  
  181.   
  182.         return parmasList;  
  183.   
  184.     }  
  185.   
  186.     /** 
  187.      * 获取登录表单input内容 
  188.      *  
  189.      * @param url 
  190.      * @return 
  191.      * @throws IOException 
  192.      * @throws ParseException 
  193.      */  
  194.     public static HashMap getLoginFormData(String url)  
  195.             throws ParseException, IOException {  
  196.         Document document = Jsoup.parse(getHtml(url));  
  197.         Elements element1 = document.getElementsByTag("form");// 找出所有form表单  
  198.         Element element = element1.select("[method=post]").first();// 筛选出提交方法为post的表单  
  199.         Elements elements = element.select("input[name]");// 把表单中带有name属性的input标签取出  
  200.         HashMap parmas = new HashMap();  
  201.         for (Element temp : elements) {  
  202.             parmas.put(temp.attr("name"), temp.attr("value"));// 把所有取出的input,取出其name,放入Map中  
  203.         }  
  204.         return parmas;  
  205.     }  
  206.   
  207.     class BookEntity {  
  208.         /** 
  209.          * 书名 
  210.          *  
  211.          */  
  212.         private String name;  
  213.         /** 
  214.          * 可借数 
  215.          */  
  216.         private String leandableNum;  
  217.         /** 
  218.          * 索引号 
  219.          */  
  220.         private String callNumber;  
  221.         /** 
  222.          * 作者 
  223.          */  
  224.         private String writer;  
  225.         /** 
  226.          * 出版社 
  227.          */  
  228.         private String publisher;  
  229.         /** 
  230.          * 还书时间 
  231.          */  
  232.         private String data2Return;  
  233.         /** 
  234.          * 借书时间 
  235.          */  
  236.         private String data2Borrowed;  
  237.         /** 
  238.          * 是否续满 
  239.          */  
  240.         private String isFullData;  
  241.   
  242.         public BookEntity() {  
  243.   
  244.         }  
  245.   
  246.         public String getName() {  
  247.             return name;  
  248.         }  
  249.   
  250.         public String getLeandableNum() {  
  251.             return leandableNum;  
  252.         }  
  253.   
  254.         public String getCallNumber() {  
  255.             return callNumber;  
  256.         }  
  257.   
  258.         public String getWriter() {  
  259.             return writer;  
  260.         }  
  261.   
  262.         public String getPublisher() {  
  263.             return publisher;  
  264.         }  
  265.   
  266.         public BookEntity setName(String name) {  
  267.             this.name = name;  
  268.             return this;  
  269.         }  
  270.   
  271.         public BookEntity setLeandableNum(String leandableNum) {  
  272.             this.leandableNum = leandableNum;  
  273.             return this;  
  274.         }  
  275.   
  276.         public BookEntity setCallNumber(String callNumber) {  
  277.             this.callNumber = callNumber;  
  278.             return this;  
  279.         }  
  280.   
  281.         public BookEntity setWriter(String writer) {  
  282.             this.writer = writer;  
  283.             return this;  
  284.         }  
  285.   
  286.         public BookEntity setPublisher(String publisher) {  
  287.             this.publisher = publisher;  
  288.             return this;  
  289.         }  
  290.   
  291.         public String getData2Return() {  
  292.             return data2Return;  
  293.         }  
  294.   
  295.         public String getData2Borrowed() {  
  296.             return data2Borrowed;  
  297.         }  
  298.   
  299.         public String getIsFullData() {  
  300.             return isFullData;  
  301.         }  
  302.   
  303.         public BookEntity setData2Return(String data2Return) {  
  304.             this.data2Return = data2Return;  
  305.             return this;  
  306.         }  
  307.   
  308.         public BookEntity setData2Borrowed(String data2Borrowed) {  
  309.             this.data2Borrowed = data2Borrowed;  
  310.             return this;  
  311.         }  
  312.   
  313.         public BookEntity setIsFullData(String isFullData) {  
  314.             this.isFullData = isFullData;  
  315.             return this;  
  316.         }  
  317.   
  318.     }  
  319.   
  320. }  

 

 

    关于Jsoup怎么使用这里就不详细说了,

    详细请查阅这个网站:http://www.open-open.com/jsoup/

 

你可能感兴趣的:(android开发技巧收集)