httpclient是apache的一个项目:http://hc.apache.org/

文档比較完好:http://hc.apache.org/httpcomponents-client-ga/tutorial/html/

这里就不啰嗦了,主要是在做demo的时候遇到的一些问题在这里总结一下:

[引用请注明出处http://blog.csdn.net/bhq2010/article/details/9210007]

1、使用连接池

虽说http协议时无连接的,但毕竟是基于tcp的,底层还是须要和server建立连接的。对于须要从同一个网站抓取大量网页的程序,应该使用连接池,否则每次抓取都和Web网站建立连接、发送请求、获得响应、释放连接,一方面效率不高,还有一方面稍不小心就会疏忽了某些资源的释放、导致网站拒绝连接(非常多网站会拒绝同一个ip的大量连接、防止DOS攻击)。

连接池的例程例如以下:

SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));
schemeRegistry.register(new Scheme("https", 443, SSLSocketFactory.getSocketFactory()));
PoolingClientConnectionManager cm = new PoolingClientConnectionManager(schemeRegistry);
cm.setMaxTotal(200);
cm.setDefaultMaxPerRoute(2);
HttpHost googleResearch = new HttpHost("research.google.com", 80);
HttpHost wikipediaEn = new HttpHost("en.wikipedia.org", 80);
cm.setMaxPerRoute(new HttpRoute(googleResearch), 30);
cm.setMaxPerRoute(new HttpRoute(wikipediaEn), 50);

SchemaRegistry的作用是注冊协议的默认port号。PoolingClientConnectionManager是池化连接管理器,即连接池,setMaxTotal设置连接池的最大连接数,setDefaultMaxPerRoute设置每一个路由(http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d5e467)上的默认连接个数,setMaxPerRoute则单独为某个网站设置最大连接个数。

从连接池中获取http client也非常方面:

DefaultHttpClient client = new DefaultHttpClient(cm);

2、设置HttpClient參数

HttpClient须要设置合适的參数,才干更好地工作。默认的參数可以应付少量的抓取工作,但找到一组合适的參数往往能改善特定情况下的抓取效果。设置參数的例程例如以下:

		DefaultHttpClient client = new DefaultHttpClient(cm);
Integer socketTimeout = 10000;
Integer connectionTimeout = 10000;
final int retryTime = 3;
client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, socketTimeout);
client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, connectionTimeout);
client.getParams().setParameter(CoreConnectionPNames.TCP_NODELAY, false);
client.getParams().setParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 1024 * 1024);
HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler()
{
@Override
public boolean retryRequest(IOException exception, int executionCount, HttpContext context)
{
if (executionCount >= retryTime)
{
// Do not retry if over max retry count
return false;
}
if (exception instanceof InterruptedIOException)
{
// Timeout
return false;
}
if (exception instanceof UnknownHostException)
{
// Unknown host
return false;
}
if (exception instanceof ConnectException)
{
// Connection refused
return false;
}
if (exception instanceof SSLException)
{
// SSL handshake exception
return false;
}
HttpRequest request = (HttpRequest) context.getAttribute(ExecutionContext.HTTP_REQUEST);
boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
if (idempotent)
{
// Retry if the request is considered idempotent
return true;
}
return false;
} };
client.setHttpRequestRetryHandler(myRetryHandler);
5、6行分别设置了Socket最大等待时间、连接最大等待时间(单位都是毫秒)。socket等待时间是指从网站下载页面和数据时,两个数据包之间的最大时间间隔,超过这个时间间隔,httpclient就觉得连接出了故障。连接最大等待时间则是指和网站建立连接时的最大等待时间,超过这个时间网站不给回应,则觉得网站无法连接。第7行设置httpclient不使用NoDelay策略。假设启用了NoDelay策略,httpclient和网站之间数据传输时将会尽可能及时地将发送缓冲区中的数据发送出去、而不考虑网络带宽的利用率,这个策略适合对实时性要求高的场景。而禁用了这个策略之后,数据传输会採用Nagle's
algorithm发送数据,该算法会充分顾及带宽的利用率,而不是传输数据的实时性。第8行设置socket缓冲区的大小(单位为字节),默认是8KB。
HttpRequestRetryHandler是负责处理请求重试的接口。在该接口的内部类中实现RetryRequest方法就可以。当httpclient发送请求之后出现异常时,就会调用这种方法。在该方法中依据已运行请求的次数、请求内容、异常信息推断是否继续重试,若继续重试返回true,否则返回false。

3、设置request header

设置request header也是非常重要的,比方设置User-Agent能够将抓取程序伪装成浏览器,骗过一些站点对爬虫的检查,设置Accept-Encoding为gzip能够建议站点以压缩格式数据传输、节省带宽等等。例程例如以下:
		HttpResponse response = null;
HttpGet get = new HttpGet(url);
get.addHeader("Accept", "text/html");
get.addHeader("Accept-Charset", "utf-8");
get.addHeader("Accept-Encoding", "gzip");
get.addHeader("Accept-Language", "en-US,en");
get.addHeader("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.160 Safari/537.22");
response = client.execute(get);
HttpEntity entity = response.getEntity();
Header header = entity.getContentEncoding();
if (header != null)
{
HeaderElement[] codecs = header.getElements();
for (int i = 0; i < codecs.length; i++)
{
if (codecs[i].getName().equalsIgnoreCase("gzip"))
{
response.setEntity(new GzipDecompressingEntity(entity));
}
}
}
return response;

各个header的含义參考http://kb.cnblogs.com/page/92320/

须要的都设上就好了。假设须要非常多不同的User-Agent轮流使用(同一个User-Agent对一个网站频繁訪问easy被识别为爬虫而杯具),能够去网上找,也能够在自己的chrome浏览器里看或者用抓包软件抓。值得注意的是设置了Accept-Encoding为gzip之后,对网站回复的内容要检查是否是压缩格式的,假设是,则解压缩,如上面例程中第9行之后的代码所看到的。

Java HttpClient使用小结的更多相关文章

  1. java并发包小结(二)

    接上一篇 java并发包小结(一):http://blog.csdn.net/aalansehaiyang52/article/details/8877579 Future 接口Future 接口允许 ...

  2. java IO 流小结

    java IO 流小结 java流类图结构 流的分类 按方向 输入流 输出流 按类型 字节流 字符流 结论:只要是处理纯文本数据,就优先考虑使用字符流. 除此之外都使用字节流.

  3. java单向加密算法小结(2)--MD5哈希算法

    上一篇文章整理了Base64算法的相关知识,严格来说,Base64只能算是一种编码方式而非加密算法,这一篇要说的MD5,其实也不算是加密算法,而是一种哈希算法,即将目标文本转化为固定长度,不可逆的字符 ...

  4. java Http编程小结

    1:什么是HTTP? 超文本传输协议(HyperText Transfer Protocol -- HTTP)是一个设计来使客户端和服务器顺利进行通讯的协议. HTTP在客户端和服务器之间以reque ...

  5. java httpclient发送json 请求 ,go服务端接收

    /***java客户端发送http请求*/package com.xx.httptest; /** * Created by yq on 16/6/27. */ import java.io.IOEx ...

  6. [Java] HttpClient有个古怪的stalecheck选项

    打开stale check会让每次http请求额外消耗15毫秒.而且stalecheck选项缺省是打开的. 这有必要吗???? 在局域网里面调用web api service的时候会死人的. http ...

  7. Java HttpClient伪造请求之简易封装满足HTTP以及HTTPS请求

    HttpClient简介 HTTP 协议可能是现在 Internet 上使用得最多.最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源.虽然在 JDK 的 jav ...

  8. java HttpClient 忽略证书的信任的实现 MySSLProtocolSocketFactory

    当不需要任何证书访问https时,java中先实现一个MySSLProtocolSocketFactory类忽略证书的信任 package com.tgb.mq.producer.utils; imp ...

  9. java httpclient post xml demo

    jar archive: http://archive.apache.org/dist/httpcomponents/ 基于httpclient 2.0 final的demo(for jdk1.5/1 ...

随机推荐

  1. activity切换时的overridePendingTransition动画效

      注意,切换方法overridePendingTransition只能在startActivity和finish方法之后调用.第一个参数为第一个Activity离开时的动画,第二参数为所进入的Act ...

  2. 一款APP从设计稿到切图过程全方位揭秘 Mark

    纯干货!一款APP从设计稿到切图过程全方位揭秘   @BAT_LCK:我本身是一名GUI设计师,所以我只站在GUI设计师的角度去把APP从项目启动到切片输出的过程写一写,相当于工作流程的介绍吧.公司不 ...

  3. dispatch_once单例初始化

    static GHCache *instance = nil; /** *  单例,静态初始化方法 * *  @return 返回一个单例 */ + (GHCache*)shareCache{ sta ...

  4. 《学习OpenCV》练习题第四章第七题abc

    题外话:一直是打算把这本书的全部课后编程题写完的,中间断了几个月,一直忙于其他事.现在开始补上. 这道题我不清楚我理解的题意是不是正确的,这道题可以练习用OpenCV实现透视变换(可以用于矫正在3维环 ...

  5. 谈FTP服务器攻击技术及其展望 (修改中)

      欢迎大家给我投票: http://2010blog.51cto.com/350944 请看下篇:谈FTP服务器攻击技术及其展望 (下)              全文完http://chengua ...

  6. 转】Mahout学习路线图

    原博文出自于: http://blog.fens.me/hadoop-mahout-roadmap/ 感谢! Mahout学习路线图 Hadoop家族系列文章,主要介绍Hadoop家族产品,常用的项目 ...

  7. CXF整合Spring发布WebService实例

    一.说明: 上一篇简单介绍了CXF以及如何使用CXF来发布一个简单的WebService服务,并且介绍了客户端的调用. 这一篇介绍如何使用CXF与spring在Web项目中来发布WebService服 ...

  8. HDU 4617 Weapon (简单三维计算几何,异面直线距离)

    Weapon Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Subm ...

  9. C# winform只有一个进程

    在做winform程序的时候,有时候需要客户只能起一个进程,不能起多个进程,用如下代码可以实现. internal static class Program { private static Mute ...

  10. RS-232-C串口通讯协议解析(硬件接口协议)

    http://www.dz3w.com/info/interface/0075524.html http://wenku.baidu.com/view/02cc247c27284b73f24250e3 ...