HTTPclient模拟登陆交大图书馆
最近想做一个图书馆的客户端,由于学校没有提供API,只能模拟登陆然后爬取数据了。
首先要解决的就是登陆问题,其实会了之后并不难,我在此竟然耗费了两天……都是一些细节问题。
采用HTTPclient模拟请求,需要注意:
- HttpClient(DefaultHttpClient)代表了一个会话,在同一个会话中,HttpClient对cookie自动进行管理(当然,也可以在程序中进行控制)。
- 在同一个会话中,当使用post或是get发起一个新的请求时,一般需要对调用前一个会话的abort()方法,否则会抛出异常。
- 有些网站登录成功后会重定向(302, 303)。如果发出的是post请求,需要从响应头中取出location,并再次向网站发送请求,以获取最终数据
- 抓取程序不要运行地过于频繁,大部分站点都有抵制刷网站机制。
- Android 使用jsoup对得到的html进行解析。
- 发送post请求,设置响应的请求头。表单体需要传入四个字段,分别为:用户名(code),密码(pin),(submit.x),(submit.y)
- 根据post请求的响应头,获取location,得到重定向的网址。
- 发送get请求,获取具体信息。如果第二个请求你又使用了一个新的HTTPclient对象,你就需要获取post请求中的cookie,并将cookie设置到get请求的请求头,否则,系统提示超过有效期。这里如果使用同一个HTTPclient,则不需要设置cookie,因为HTTPclient会帮你管理cookie。
- 查阅资料得到一点说明:HttpClient支持自动转向处理,但是象POST和PUT方式这种要求接受后继服务的请求方式,暂时不支持自动转向,因此如果碰到POST方式提交后返回的是301或者302的话需要自己处理。
<span style="font-size:14px;">package com.ali.login; import java.util.ArrayList; import java.util.List; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpConnectionParams; import org.apache.http.protocol.HTTP; import org.apache.http.util.EntityUtils; public class LibraryUtil { private static final String baseUrl = "http://innopac.lib.xjtu.edu.cn"; private static String POST_URL = "http://innopac.lib.xjtu.edu.cn/patroninfo*chx"; private static String KEY_CODE = "code"; private static String KEY_PIN = "pin"; private static String KEY_Submit_x = "submit.x";// 26 private static String KEY_Submit_y = "submit.y";// 20 // The HttpClient is used in one session private static HttpResponse response; private static HttpClient httpclient = null; private static String resultHtml = null; /** * @param args */ public static void main(String[] args) { boolean isConn = login("2111******", "********"); if (isConn) { System.out.println(resultHtml); } } /** * 登陆 * */ public static boolean login(String userName, String password) { HttpGet httpget = null; HttpPost httppost = null; try { httpclient = new DefaultHttpClient(); // 看作是浏览器 BasicHttpParams httpParams = new BasicHttpParams(); HttpConnectionParams.setConnectionTimeout(httpParams, 10000); HttpConnectionParams.setSoTimeout(httpParams, 10000); List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); nameValuePairs.add(new BasicNameValuePair(KEY_CODE, userName)); nameValuePairs.add(new BasicNameValuePair(KEY_PIN, password)); nameValuePairs.add(new BasicNameValuePair(KEY_Submit_x, Integer .toString(50))); nameValuePairs.add(new BasicNameValuePair(KEY_Submit_y, Integer .toString(25))); httppost = new HttpPost(POST_URL); httppost.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"); httppost.setHeader("Accept-Language", "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3"); httppost.setHeader("Accept-Encoding", "gzip, deflate"); httppost.setHeader("Referer", "http://innopac.lib.xjtu.edu.cn/patroninfo*chx"); httppost.setHeader("Connection", "keep-alive"); httppost.setHeader("Content-Type", "application/x-www-form-urlencoded"); httppost.setHeader("Host", "innopac.lib.xjtu.edu.cn"); httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); response = httpclient.execute(httppost);// 发送post请求 int code = response.getStatusLine().getStatusCode(); System.out.println(response.getStatusLine()); // 200说明密码或用户名错误,302则说明正常登陆 if (code == 200) { System.out.println("用户名或密码错误,请重新登陆"); return false; } else if (code == 302) { System.out.println("登陆成功,跳转中..."); String location = response.getHeaders("Location")[0].getValue(); System.out.println(location); httppost.abort(); httpget = new HttpGet(baseUrl + location); response = httpclient.execute(httpget);// 发送get请求 code = response.getStatusLine().getStatusCode(); System.out.println(response.getStatusLine()); if (code == 200) { if (response != null) { resultHtml = EntityUtils.toString(response.getEntity(), HTTP.UTF_8); } return true; } } } catch (Exception e) { e.printStackTrace(); } finally { httpget.abort(); httpclient.getConnectionManager().shutdown(); } return false; } } </span>
参考:http://www.iteye.com/problems/65312
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。