zoukankan      html  css  js  c++  java
  • HttpClient + Jsoup 模拟登陆,解析HTML,信息筛选(广工图书馆)

     

    HttpClient + Jsoup 模拟登陆,解析HTML获取信息

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

    思路如下:

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

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

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

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



     
     

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

    Html代码 
    1. <form name="aspnetForm" method="post" action="login.aspx?ReturnUrl=%2fuser%2fuserinfo.aspx" onsubmit="javascript:return WebForm_OnSubmit();" id="aspnetForm">  
    2. <div>  
    3. <input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />  
    4. <input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />  
    5. <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTE0MjY3MDAxNzcPZBYCZg9kFgoCAQ8PFgIeCEltYWdlVXJsBRt+XGltYWdlc1xoZWFkZXJvcGFjNGdpZi5naWZkZAICDw8WAh4EVGV4dAUt5bm/5Lic5bel5Lia5aSn5a2m5Zu+5Lmm6aaG5Lmm55uu5qOA57Si57O757ufZGQCAw8PFgIfAQUcMjAxM+W5tDAz5pyIMDXml6UgIOaYn+acn+S6jGRkAgQPZBYEZg9kFgQCAQ8WAh4LXyFJdGVtQ291bnQCCBYSAgEPZBYCZg8VAwtzZWFyY2guYXNweAAM55uu5b2V5qOA57SiZAICD2QWAmYPFQMTcGVyaV9uYXZfY2xhc3MuYXNweAAM5YiG57G75a+86IiqZAIDD2QWAmYPFQMOYm9va19yYW5rLmFzcHgADOivu+S5puaMh+W8lWQCBA9kFgJmDxUDCXhzdGIuYXNweAAM5paw5Lmm6YCa5oqlZAIFD2QWAmYPFQMUcmVhZGVycmVjb21tZW5kLmFzcHgADOivu+iAheiNkOi0rWQCBg9kFgJmDxUDE292ZXJkdWVib29rc19mLmFzcHgADOaPkOmGkuacjeWKoWQCBw9kFgJmDxUDEnVzZXIvdXNlcmluZm8uYXNweAAP5oiR55qE5Zu+5Lmm6aaGZAIID2QWAmYPFQMbaHR0cDovL2xpYnJhcnkuZ2R1dC5lZHUuY24vAA/lm77kuabppobpppbpobVkAgkPZBYCAgEPFgIeB1Zpc2libGVoZAIDDxYCHwJmZAIBD2QWBAIDD2QWBAIBDw9kFgIeDGF1dG9jb21wbGV0ZQUDb2ZmZAIHDw8WAh8BZWRkAgUPZBYGAgEPEGRkFgFmZAIDDxBkZBYBZmQCBQ8PZBYCHwQFA29mZmQCBQ8PFgIfAQWlAUNvcHlyaWdodCAmY29weTsyMDA4LTIwMDkuIFNVTENNSVMgT1BBQyA0LjAxIG9mIFNoZW56aGVuIFVuaXZlcnNpdHkgTGlicmFyeS4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuPGJyIC8+54mI5p2D5omA5pyJ77ya5rex5Zyz5aSn5a2m5Zu+5Lmm6aaGIEUtbWFpbDpzenVsaWJAc3p1LmVkdS5jbmRkZL5QuJMrEZz+0UxuTVpXZ/EaY5A4" />  
    6. </div>  
    7.   
    8. <script type="text/javascript">  
    9. //<![CDATA[ 
    10. var theForm = document.forms['aspnetForm']; 
    11. if (!theForm) { 
    12.     theForm = document.aspnetForm; 
    13. function __doPostBack(eventTarget, eventArgument) { 
    14.     if (!theForm.onsubmit || (theForm.onsubmit() != false)) { 
    15.         theForm.__EVENTTARGET.value = eventTarget; 
    16.         theForm.__EVENTARGUMENT.value = eventArgument; 
    17.         theForm.submit(); 
    18.     } 
    19. //]]>  
    20. </script>  
    21.   
    22.   
    23. <script src="/WebResource.axd?d=kbLQnwjf5uNQN4GcWRC5kD1rIySOzkR3uLyKE5xUO0j4Fa2lQPZwQlk_qYaspRXtlojncSBfRJNkA00qXOMQqsKd8WY1&amp;t=634751988274393221" type="text/javascript"></script>  
    24.   
    25.   
    26. <script src="/WebResource.axd?d=nsbO6ZJty6_6fuRufFNYnRiJ-xEoD0xQr70NX6g0v64gngATPLSnyyt7jyZkELLW6THXmh92_m0Y5TyvhES_-JroQeU1&amp;t=634751988274393221" type="text/javascript"></script>  
    27. <script type="text/javascript">  
    28. //<![CDATA[ 
    29. function WebForm_OnSubmit() { 
    30. if (typeof(ValidatorOnSubmit) == "function" && ValidatorOnSubmit() == false) return false; 
    31. return true; 
    32. //]]>  
    33. </script>  
    34.   
    35. <div>  
    36.   
    37.     <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWBQKa7ezdCwKOmK5RApX9wcYGAsP9wL8JAqW86pcIaBhXmFYzd5pGDTk/afln2TfArPw=" />  
    38. </div>  
    39. <input name="ctl00$ContentPlaceHolder1$txtlogintype" type="hidden" id="ctl00_ContentPlaceHolder1_txtlogintype" value="0" />  
    40. <div id="Login" class="clearFix">  
    41.     <div class="LoginTitle">  
    42.         登录我的图书馆  
    43.     </div>  
    44.       
    45.       
    46.     <div class="LeftLogin">  
    47.             <div class="LoginDiv">  
    48.                   
    49.                 <div class="loginContent">  
    50.                     <div class="loginInfo">  
    51.                         <span class="leftInfo">图书证号:</span>  
    52.                         <span class="rightInfo">  
    53.                             <input name="ctl00$ContentPlaceHolder1$txtUsername_Lib" type="text" id="ctl00_ContentPlaceHolder1_txtUsername_Lib" class="txtInput" autocomplete="off" /><span id="ctl00_ContentPlaceHolder1_rfv_UserName_Lib" style="color:Red;display:none;">请输入证号</span>  
    54.                         </span>  
    55.                     </div>  
    56.                     <div class="loginInfo">  
    57.                         <span class="leftInfo">密&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;码:</span>  
    58.                         <span class="rightInfo">  
    59.                             <input name="ctl00$ContentPlaceHolder1$txtPas_Lib" type="password" id="ctl00_ContentPlaceHolder1_txtPas_Lib" class="txtInput" /><span id="ctl00_ContentPlaceHolder1_rfv_Password_Lib" style="color:Red;display:none;">请输入密码</span>  
    60.                         </span>  
    61.                     </div>  
    62.                     <div>  
    63.                         <span id="ctl00_ContentPlaceHolder1_lblErr_Lib"></span>  
    64.                     </div>  
    65.                     <div class="loginInfo">  
    66.                         <input type="submit" name="ctl00$ContentPlaceHolder1$btnLogin_Lib" value="登录" onclick="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(&quot;ctl00$ContentPlaceHolder1$btnLogin_Lib&quot;, &quot;&quot;, true, &quot;&quot;, &quot;&quot;, false, false))" id="ctl00_ContentPlaceHolder1_btnLogin_Lib" class="btn" />  
    67.                         <input type="button" value="清空" onclick="rset()" class="btn"/>  
    68.                     </div>  
    69.                 </div>  
    70.             </div>  
    71.         </div>  
    72.         <div class="RightDescription">  
    73.         <img src="images/pin.gif" />  <br/>  
    74.         1.  如果您使用的是公共电脑,请在使用完毕后,务必退出登录,以保安全。<br />  
    75.         2.  首次登录,请先<a href="changepas.aspx">修改初始密码</a>。  
    76.         </div>  
    77.           
    78.           
    79.           
    80.       
    81.       
    82. </div>  
    83.   
    84. <script type="text/javascript">  
    85. //<![CDATA[ 
    86. var Page_Validators =  new Array(document.getElementById("ctl00_ContentPlaceHolder1_rfv_UserName_Lib"), document.getElementById("ctl00_ContentPlaceHolder1_rfv_Password_Lib")); 
    87. //]]>  
    88. </script>  
    89.   
    90. <script type="text/javascript">  
    91. //<![CDATA[ 
    92. var ctl00_ContentPlaceHolder1_rfv_UserName_Lib = document.all ? document.all["ctl00_ContentPlaceHolder1_rfv_UserName_Lib"] : document.getElementById("ctl00_ContentPlaceHolder1_rfv_UserName_Lib"); 
    93. ctl00_ContentPlaceHolder1_rfv_UserName_Lib.controltovalidate = "ctl00_ContentPlaceHolder1_txtUsername_Lib"; 
    94. ctl00_ContentPlaceHolder1_rfv_UserName_Lib.focusOnError = "t"; 
    95. ctl00_ContentPlaceHolder1_rfv_UserName_Lib.errormessage = "请输入证号"; 
    96. ctl00_ContentPlaceHolder1_rfv_UserName_Lib.display = "Dynamic"; 
    97. ctl00_ContentPlaceHolder1_rfv_UserName_Lib.evaluationfunction = "RequiredFieldValidatorEvaluateIsValid"; 
    98. ctl00_ContentPlaceHolder1_rfv_UserName_Lib.initialvalue = ""; 
    99. var ctl00_ContentPlaceHolder1_rfv_Password_Lib = document.all ? document.all["ctl00_ContentPlaceHolder1_rfv_Password_Lib"] : document.getElementById("ctl00_ContentPlaceHolder1_rfv_Password_Lib"); 
    100. ctl00_ContentPlaceHolder1_rfv_Password_Lib.controltovalidate = "ctl00_ContentPlaceHolder1_txtPas_Lib"; 
    101. ctl00_ContentPlaceHolder1_rfv_Password_Lib.focusOnError = "t"; 
    102. ctl00_ContentPlaceHolder1_rfv_Password_Lib.errormessage = "请输入密码"; 
    103. ctl00_ContentPlaceHolder1_rfv_Password_Lib.display = "Dynamic"; 
    104. ctl00_ContentPlaceHolder1_rfv_Password_Lib.evaluationfunction = "RequiredFieldValidatorEvaluateIsValid"; 
    105. ctl00_ContentPlaceHolder1_rfv_Password_Lib.initialvalue = ""; 
    106. //]]>  
    107. </script>  
    108.   
    109.   
    110. <script type="text/javascript">  
    111. //<![CDATA[ 
    112.  
    113. var Page_ValidationActive = false; 
    114. if (typeof(ValidatorOnLoad) == "function") { 
    115.     ValidatorOnLoad(); 
    116.  
    117. function ValidatorOnSubmit() { 
    118.     if (Page_ValidationActive) { 
    119.         return ValidatorCommonOnSubmit(); 
    120.     } 
    121.     else { 
    122.         return true; 
    123.     } 
    124.         //]]>  
    125. </script>  
    126. </form>  

    里面很多代码,我们要从中提取出我们登陆所需要的表单信息,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<NameValuePair> initLoginParmas(String userName,  
    11.             String passWord) throws ParseException, IOException {  
    12.         List<NameValuePair> parmasList = new ArrayList<NameValuePair>();  
    13.         HashMap<String, String> parmasMap = getLoginFormData(LoginUrl);  
    14.         Set<String> 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<String> 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<String, String> 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<String, String> parmas = new HashMap<String, String>();  
    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+W5tDAz5pyIMDXml6UgIOaYn+acn+S6jGRkAgQPZBYEZg9kFgQCAQ8WAh4LXyFJdGVtQ291bnQCCBYSAgEPZBYCZg8VAwtzZWFyY2guYXNweAAM55uu5b2V5qOA57SiZAICD2QWAmYPFQMTcGVyaV9uYXZfY2xhc3MuYXNweAAM5YiG57G75a+86IiqZAIDD2QWAmYPFQMOYm9va19yYW5rLmFzcHgADOivu+S5puaMh+W8lWQCBA9kFgJmDxUDCXhzdGIuYXNweAAM5paw5Lmm6YCa5oqlZAIFD2QWAmYPFQMUcmVhZGVycmVjb21tZW5kLmFzcHgADOivu+iAheiNkOi0rWQCBg9kFgJmDxUDE292ZXJkdWVib29rc19mLmFzcHgADOaPkOmGkuacjeWKoWQCBw9kFgJmDxUDEnVzZXIvdXNlcmluZm8uYXNweAAP5oiR55qE5Zu+5Lmm6aaGZAIID2QWAmYPFQMbaHR0cDovL2xpYnJhcnkuZ2R1dC5lZHUuY24vAA/lm77kuabppobpppbpobVkAgkPZBYCAgEPFgIeB1Zpc2libGVoZAIDDxYCHwJmZAIBD2QWBAIDD2QWBAIBDw9kFgIeDGF1dG9jb21wbGV0ZQUDb2ZmZAIHDw8WAh8BZWRkAgUPZBYGAgEPEGRkFgFmZAIDDxBkZBYBZmQCBQ8PZBYCHwQFA29mZmQCBQ8PFgIfAQWlAUNvcHlyaWdodCAmY29weTsyMDA4LTIwMDkuIFNVTENNSVMgT1BBQyA0LjAxIG9mIFNoZW56aGVuIFVuaXZlcnNpdHkgTGlicmFyeS4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuPGJyIC8+54mI5p2D5omA5pyJ77ya5rex5Zyz5aSn5a2m5Zu+5Lmm6aaGIEUtbWFpbDpzenVsaWJAc3p1LmVkdS5jbmRkZL5QuJMrEZz+0UxuTVpXZ/EaY5A4  
    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<NameValuePair> parmasList = new ArrayList<NameValuePair>();  
    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. <a href="bookborrowed.aspx" >当前借阅情况和续借</a>  

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

    获取代码如下:

    Java代码 
    1. public static void getMyBorrowedBooks() {  
    2.         try {  
    3.             Document document = Jsoup.parse(login());  
    4.             Elements elements1 = document  
    5.                     .getElementsContainingOwnText("当前借阅情况和续借");// 通过text关键字找到所要的<a>标签  
    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. <tr>              
    2.            <td width="5%">  
    3.              
    4.              
    5.            续满  
    6.              
    7.              
    8.            </td>  
    9.            <td width="10%">2013-04-10</td>  
    10.            <td width="35%"><a href="../bookinfo.aspx?ctrlno=571892" target="_blank">编写高质量代码 [专著]:改善Java程序的151个建议=Writing solw Java cove:151 suggestons to improve your Java program/秦小波著</a></td>  
    11.            <td width="5%"> </td>  
    12.            <td width="8%">中文图书</td>  
    13.            <td width="7%">A2973844</td>  
    14.            <td width="10%">2012-12-05</td>  
    15.         </tr>  
    16.          
    17.        <tr>         

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

    Java代码 
    1. /** 
    2.      * 获取借书情况具体数据(List<BookEntity>) 
    3.      *  
    4.      * @param src 
    5.      * @return List<BookEntity> 
    6.      */  
    7.     private static List<BookEntity> getBookBorrowedData(String src) {  
    8.         List<BookEntity> data = new ArrayList<BookEntity>();  
    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. <strong>完整代码:</strong>  
    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关键字找到所要的<a>标签  
    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<BookEntity>) 
    64.      *  
    65.      * @param src 
    66.      * @return List<BookEntity> 
    67.      */  
    68.     private static List<BookEntity> getBookBorrowedData(String src) {  
    69.         List<BookEntity> data = new ArrayList<BookEntity>();  
    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<NameValuePair> parmasList = new ArrayList<NameValuePair>();  
    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<NameValuePair> initLoginParmas(String userName,  
    158.             String passWord) throws ParseException, IOException {  
    159.         List<NameValuePair> parmasList = new ArrayList<NameValuePair>();  
    160.         HashMap<String, String> parmasMap = getLoginFormData(LoginUrl);  
    161.         Set<String> 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<String> 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<String, String> 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<String, String> parmas = new HashMap<String, String>();  
    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/

  • 相关阅读:
    解决网站出现Error Establishing Database Connection问题
    Linux发行版时间线分支图最新版
    rem.js,移动多终端适配
    几种常用JavaScript设计模式es6
    文件上传,8种场景
    react动态添加样式:style和className
    记录我的 python 学习历程-Day13 匿名函数、内置函数 II、闭包
    记录我的 python 学习历程-Day12 生成器/推导式/内置函数Ⅰ
    记录我的 python 学习历程-Day11 两个被忽视的坑、补充知识点、函数名的应用、新版格式化输出、迭代器
    记录我的 python 学习历程-Day10 函数进阶
  • 原文地址:https://www.cnblogs.com/chenchuangfeng/p/2987334.html
Copyright © 2011-2022 走看看