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 ...
随机推荐
- js垃圾回收机制理解
原理 找到不再被使用的变量,然后释放其占用的内存,但这个过程不是时时的,因为其开销比较大, 所以垃圾回收器会按照固定时间间隔周期性的执行 回收方式 a.标记清除 当变量进入环境时,将这个变量标记为“进 ...
- BZOJ3569: DZY Loves Chinese II(线性基构造)
Description 神校XJ之学霸兮,Dzy皇考曰JC. 摄提贞于孟陬兮,惟庚寅Dzy以降. 纷Dzy既有此内美兮,又重之以修能. 遂降临于OI界,欲以神力而凌♂辱众生. 今Dzy有一魞歄图, ...
- Git 远程仓库默认权限问题的解决
多人共同开发维护一个项目时,对整个项目文件互有拉取.推送等行为.为防止操作时文件权限出现冲突,可有以下2种方法解决: 1. 本地git的远端设置中,连接远程仓库时多人使用同一个用户名,该用户名为git ...
- selenium使用报错“selenium.common.exceptions.WebDriverException: Message: 'geckodriver' executable needs to be in PATH.”
安装了python3,使用pip安装了selenium,但是在使用时,报了“selenium.common.exceptions.WebDriverException: Message: 'gecko ...
- OpenJDK源码研究笔记(十):枚举的高级用法,枚举实现接口,竟是别有洞天
在研究OpenJDK,Java编译器javac源码的过程中,发现以下代码. 顿时发现枚举类竟然也有如此"高端大气上档次"的用法. 沙场点兵(用法源码) com.sun.tools. ...
- 高速排序——JAVA实现(图文并茂)
高快省的排序算法 有没有既不浪费空间又能够快一点的排序算法呢?那就是"高速排序"啦! 光听这个名字是不是就认为非常高端呢. 如果我们如今对"6 1 2 7 9 3 4 5 ...
- 【java】itoo项目实战之大数据查询之使用 new map 优化hibernate之级联查询
在我的上一篇博客<[java]itoo项目实战之hibernate 懒载入优化性能>中,我曾提到过学生数据有2万条,查询数据十分的慢,这是让人非常受不了的事情.看着页面进度条一直转着圈圈, ...
- 欢天喜地迎国庆,国产开源编程语言 RPP 1.87 公布!
更新例如以下: 1.支持超级宏 2.修复bug 下载地址: https://github.com/roundsheep/rpp 超级宏能够随意定义语法,制约你的仅仅有想象力: void main() ...
- C# 插入排序 冒泡排序 选择排序 高速排序 堆排序 归并排序 基数排序 希尔排序
C# 插入排序 冒泡排序 选择排序 高速排序 堆排序 归并排序 基数排序 希尔排序 以下列出了数据结构与算法的八种基本排序:插入排序 冒泡排序 选择排序 高速排序 堆排序 归并排序 基数排序 希尔排序 ...
- Google开源新的 RISC-V IP核: “BottleRocket”(https://cnrv.io)
BottleRocket是RISCV RV32IMC的实现. Google在2017年11月29日在Github上非官方开源了BottleRocket的RTL代码,同时表明这并不是一个官方支持的Goo ...