httpclient 模拟浏览器动作需注意的cookie和HTTP头等信息
转自:http://resolute.javaeye.com/blog/491701
commons-httpclient是apache下的一个开源项目,提供了一个纯java实现的http客户端。使用它能够非常方便发送HTTP请求,接受HTTP应答,自己主动管理Cookie等等。
对于contact-list类库来说,须要使用的功能有,自己主动管理Cookie,设置HTTP头。发送HTTP请求,接受HTTP应答,转发HTTP重定向,还有输出HTTP请求/应答日志,以下对这些功能的实现进行解释:
1. 自己主动管理Cookie
view source
print?
1.public EmailImporter(String email, String password, String encoding) {
2. ......
3. client = new HttpClient();
4. client.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
5. client.getParams().setParameter("http.protocol.single-cookie-header", true);
6.}
当中将HttpClient的Cookie策略设置为CookiePolicy.BROWSER_COMPATIBILITY,即表示java client将依照浏览器的方式来自己主动处理Cookie。当然你也能够在执行过程中手动调整cookie。比方:
hotmail登录之前须要设置当前时间的Cookie:
view source
print?
1.client.getState().addCookie(new Cookie("login.live.com", "CkTst", "G" + new Date().getTime()));
只是,httpclient似乎没有提供删除cookie的功能,于是我添加了两个cookie管理的接口。一个是保留指定的cookies,一个是删除指定的cookies:
view source
print?
01.protected void retainCookies(String[] cookieNames) {
02. Cookie[] cookies = client.getState().getCookies();
03. ArrayList<Cookie> retainCookies = new ArrayList<Cookie>();
04. for (Cookie cookie : cookies) {
05. if (Arrays.binarySearch(cookieNames, cookie.getName()) >= 0) {
06. retainCookies.add(cookie);
07. }
08. }
09. client.getState().clearCookies();
10. client.getState().addCookies(retainCookies.toArray(new Cookie[0]));
11.}
12.
13.protected void removeCookies(String[] cookieNames) {
14. Cookie[] cookies = client.getState().getCookies();
15. ArrayList<Cookie> retainCookies = new ArrayList<Cookie>();
16. for (Cookie cookie : cookies) {
17. if (Arrays.binarySearch(cookieNames, cookie.getName()) < 0) {
18. retainCookies.add(cookie);
19. }
20. }
21. client.getState().clearCookies();
22. client.getState().addCookies(retainCookies.toArray(new Cookie[0]));
23.}
2. 设置HTTP头:
http头的设置,能够让邮件server觉得是在和浏览器打交道,而避免被refuse的可能:
view source
print?
01.private void setHeaders(HttpMethod method) {
02. method.setRequestHeader("Accept", "text/html,application/xhtml+xml,application/xml;");
03. method.setRequestHeader("Accept-Language", "zh-cn");
04. method.setRequestHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3");
05. method.setRequestHeader("Accept-Charset", encoding);
06. method.setRequestHeader("Keep-Alive", "300");
07. method.setRequestHeader("Connection", "Keep-Alive");
08. method.setRequestHeader("Cache-Control", "no-cache");
09.}
另外,在GET和POST的时候设置referer值。以及在POST的时候设置Content-Type:
view source
print?
1.protected String doPost(String actionUrl, NameValuePair[] params, String referer) throws HttpException, IOException {
2. ......
3. method.setRequestHeader("Referer", referer);
4. method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
5. ......
6.}
3. 发送HTTP请求,接收HTTP应答。
在contact-list中仅仅使用了GET和POST请求,我也做了简单的封装:
view source
print?
01.protected String doGet(String url, String referer) throws HttpException, IOException {
02. GetMethod method = new GetMethod(url);
03. setHeaders(method);
04. method.setRequestHeader("Referer", referer);
05. // log request
06. client.executeMethod(method);
07. String responseStr = readInputStream(method.getResponseBodyAsStream());
08. // log response
09. method.releaseConnection();
10. lastUrl = method.getURI().toString();
11. return responseStr;
12.}
13.
14.protected String doPost(String actionUrl, NameValuePair[] params, String referer) throws HttpException, IOException {
15. PostMethod method = new PostMethod(actionUrl);
16. setHeaders(method);
17. method.setRequestHeader("Referer", referer);
18. method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
19. method.setRequestBody(params);
20. // log request
21. client.executeMethod(method);
22. String responseStr = readInputStream(method.getResponseBodyAsStream());
23. // log response
24. method.releaseConnection();
25. if (method.getResponseHeader("Location") != null) {
26. // do redirect
27. } else {
28. lastUrl = method.getURI().toString();
29. return responseStr;
30. }
31.}
4. HTTP重定向,主要是两种,一种是依据HTTP头的Location
view source
print?
1.if (method.getResponseHeader("Location").getValue().startsWith("http")) {
2. return doGet(method.getResponseHeader("Location").getValue());
3.} else {
4. return doGet("http://" + getResponseHost(method) + method.getResponseHeader("Location").getValue());
5.}
还有一种是依据javascript中的window.location.replace。
5. 输出请求/应答日志。这个对调试很重要:
view source
print?
01.private void logGetRequest(GetMethod method) throws URIException {
02. logger.debug("do get request: " + method.getURI().toString());
03. logger.debug("header:/n" + getHeadersStr(method.getRequestHeaders()));
04. logger.debug("cookie:/n" + getCookieStr());
05.}
06.
07.private void logGetResponse(GetMethod method, String responseStr) throws URIException {
08. logger.debug("do get response: " + method.getURI().toString());
09. logger.debug("header: /n" + getHeadersStr(method.getResponseHeaders()));
10. logger.debug("body: /n" + responseStr);
11.}
12.
13.private void logPostRequest(PostMethod method) throws URIException {
14. logger.debug("do post request: " + method.getURI().toString());
15. logger.debug("header:/n" + getHeadersStr(method.getRequestHeaders()));
16. logger.debug("body:/n" + getPostBody(method.getParameters()));
17. logger.debug("cookie:/n" + getCookieStr());
18.}
19.
20.private void logPostResponse(PostMethod method, String responseStr) throws URIException {
21. logger.debug("do post response:" + method.getURI().toString());
22. logger.debug("header:/n" + getHeadersStr(method.getResponseHeaders()));
23. logger.debug("body:/n" + responseStr);
24.}
25.
26.private String getHeadersStr(Header[] headers) {
27. StringBuilder builder = new StringBuilder();
28. for (Header header : headers) {
29. builder.append(header.getName()).append(": ").append(header.getValue()).append("/n");
30. }
31. return builder.toString();
32.}
33.
34.private String getPostBody(NameValuePair[] postValues) {
35. StringBuilder builder = new StringBuilder();
36. for (NameValuePair pair : postValues) {
37. builder.append(pair.getName()).append(":").append(pair.getValue()).append("/n");
38. }
39. return builder.toString();
40.}
41.
42.private String getCookieStr() {
43. Cookie[] cookies = client.getState().getCookies();
44. StringBuilder builder = new StringBuilder();
45. for (Cookie cookie : cookies) {
46. builder.append(cookie.getDomain()).append(":")
47. .append(cookie.getName()).append("=").append(cookie.getValue()).append(";")
48. .append(cookie.getPath()).append(";")
49. .append(cookie.getExpiryDate()).append(";")
50. .append(cookie.getSecure()).append(";/n");
51. }
52. return builder.toString();
53.}
httpclient 模拟浏览器动作需注意的cookie和HTTP头等信息的更多相关文章
- JAVA--利用HttpClient模拟浏览器登陆请求获取响应的Cookie
在通过java采集网页数据时,我们常常会遇到这样的问题: 站点需要登陆才能访问 而这种网站,一般都会对请求进行账号密码的验证,验证的方式也有多种,需要具体分析. 今天分析其中的一种情况: 站点对登陆密 ...
- httpclient模拟浏览器get\post
一般的情况下我们都是使用IE或者Navigator浏览器来访问一个WEB服务器,用来浏览页面查看信息或者提交一些数据等等.所访问的这些页面有的仅 仅是一些普通的页面,有的需要用户登录后方可使用,或者需 ...
- httpClient模拟浏览器发请求
一.介绍 httpClient是Apache公司的一个子项目, 用来提高高效的.最新的.功能丰富的支持http协议的客户端编程工具包.完成可以模拟浏览器发起请求行为. 二.简单使用例子 : 模拟浏览器 ...
- httpclient模拟浏览器訪问站点
HttpClient 是 Apache Jakarta Common 下的子项目.能够用来提供高效的.最新的.功能丰富的支持 HTTP 协议的client编程工具包.而且它支持 HTTP 协议最新的版 ...
- Java语言使用HttpClient模拟浏览器登录
使用HttpClient来模拟浏览器登录网站,然后可以进行操作,比如发布信息等 第一步:获取实际的post网址,(不考虑复杂情况下) 1.需要使用到firefox的httpfox插件,httpfox中 ...
- httpclient模拟浏览器
package com.java.httpclient; import java.io.IOException; import org.apache.http.HttpEntity; import o ...
- 关于HttpClient模拟浏览器请求的參数乱码问题解决方式
转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/44407297 http://www.llwjy.com/blogdetail/9 ...
- 20200726_java爬虫_使用HttpClient模拟浏览器发送请求
浏览器获取数据: 打开浏览器 ==> 输入网址 ==> 回车查询 ==> 返回结果 ==> 浏览器显示结果数据 HttpClient获取数据: 创建HttpClient ==& ...
- 使用HttpClient配置代理服务器模拟浏览器发送请求调用接口测试
在调用公司的某个接口时,直接通过浏览器配置代理服务器可以请求到如下数据: 请求url地址:http://wwwnei.xuebusi.com/rd-interface/getsales.jsp?cid ...
随机推荐
- mysql not in用法
select * from zan where uid not in(select uid from zan where zhongjiang !=0) group by uid order by r ...
- 03015_DBUtils
1.概述 (1)如果只使用JDBC进行开发,我们会发现冗余代码过多,为了简化JDBC开发,本案例我们讲采用apache commons组件一个成员:DBUtils : (2)DBUtils就是JDBC ...
- 从零開始的Android新项目7 - Data Binding入门篇
Data Binding自从去年的Google I/O公布到至今,也有近一年的时间了.这一年来,从Beta到如今比較完好的版本号.从Android Studio 1.3到如今2.1.2的支持,能够说D ...
- [Parcel] Bundle a React App with Parcel
Parcel comes in as the new cool kid in the bundlers world. Unlike other bundlers which take lots of ...
- Maven实战(八)---模块划分
为了防止传递依赖,我们各个模块之间尽量用直接依赖的方式.本篇文章介绍多模块化开发.我们做过Maven项目的都知道.我们的项目一般都是分模块的,每一个模块都会相应着一个POM.xml文件,它们之间通过继 ...
- 新辰:十种外链终极方法 让SEOer外链之路不再孤独!
大家都知道,外链就是指从别的站点导入到自己站点的链接.导入链接对于新辰站点优化来说是很重要的一个过程.因此,新辰觉得.对于中小型站点来说.外链但是优化的重中之重! 由于也有了"外链专员&qu ...
- es67
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- adb logcat 使用
之前打印log的时候,使用的是别人配置好的快捷键,结果现在快捷键没有配置,具体的log命令就不会了.今天上网查了一下,记录下来 打印的log是 android.util.Log.e("zha ...
- How to install Armbian on Orange Pi Plus 2e
bian on Orange Pi Plus 2e How to install Armbian on Orange Pi Plus 2e Armbian on the microSD You jus ...
- js关于循环的理解
学习任何语言都离不开循环,js也是一样,看了网上的资料,整理一份关于js循环的理解. 1.最基础循环,js和其他高级语言一样使用for.while循环 (function() { for(var i= ...