java爬虫之HttpClient的使用

一、简介

    HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包。它实现了所有的HTTP方法(GET、POST、PUT、HEAD等),支持自动重定向,支持HTTPS协议,支持代理服务器等丰富的功能。

二、基本的使用

1、创建HttpClient实例

    1.1 现在的网站,通常使用SSL证书来保证信息传输的安全性,所以我们需要配置SSL证书,并且绕过证书安全检测。

RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder.<ConnectionSocketFactory>create();
        ConnectionSocketFactory plainSF = new PlainConnectionSocketFactory();
        registryBuilder.register("http", plainSF);
        try {
            KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            TrustStrategy anyTrustStrategy = new TrustStrategy() {
                @Override
                public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
                    return true;
                }
            };
            SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, new TrustManager[] {new X509ExtendedTrustManager() {
                //TODO 实现方法体全部为空即可
            }}, new SecureRandom());
            LayeredConnectionSocketFactory sslSF = new SSLConnectionSocketFactory(sslContext,
                    SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            registryBuilder.register("https", sslSF);
        } catch (KeyStoreException e) {
            throw new RuntimeException(e);
        } catch (KeyManagementException e) {
            throw new RuntimeException(e);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
        Registry<ConnectionSocketFactory> registry = registryBuilder.build();

    1.2 HttpClient的连接管理池的配置,这一部分非常重要,缺少某些配置会导致程序中出现难以发现的致命错误。

PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(registry);
connManager.setDefaultMaxPerRoute(20);//默认每个连接的最大路由为2个,在这里设置为20,这个太小,在并发时会导致线程挂死
connManager.setMaxTotal(20);//设置连接的最大数  

    1.3 设置重新请求策略

HttpRequestRetryHandler retryHandler = new HttpRequestRetryHandler() {
            @Override
            public boolean retryRequest(IOException exception,
                                        int executionCount, HttpContext context) {
                if (executionCount >= 3) {
                    return false;
                }
                if (exception instanceof NoHttpResponseException) {
                    return true;
                } else if (exception instanceof ClientProtocolException) {
                    return true;
                }else if(exception instanceof SocketTimeoutException){
                    return true;
                }
                return false;
            }
        };

    1.4 通常我们需要保存网站的cookie,在HttpClient中BasicCookieStore存储网站的cookie

CookieStore cookieStore = new BasicCookieStore();

    1.5 实例化一个HttpClient对象,下面列举常用几个配置项

CloseableHttpClient httpClient = HttpClientBuilder.create()
                //.setProxy(new HttpHost("127.0.0.1", 8888)) 设置本地代理
                .setConnectionManager(connManager)//设置连接池
                .setDefaultCookieStore(cookieStore)//设置cookie存储对象
                .setRedirectStrategy(new LaxRedirectStrategy())//设置重定向策略
                .setRetryHandler(retryHandler).build();//设置重新请求策略

2、GET、POST请求

   request的设置,我们可以更具需要配置请求,例如请求和传输超时时间、设置使用代理,设置是否自动请求转发,相比于在实例HttpClient中设置灵活很多。

RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(SocketTimeout)
                    .setConnectTimeout(ConnectTimeout).build();// 设置请求和传输超时时间

    2.1 GET请求例子  

String url = "https://mail.qq.com"
HttpGet httpGet = new HttpGet(url);//实例httpGet请求
httpGet.setConfig(requestConfig);//设置请求配置
httpGet.addHeader("Accept", "text/plain, */*; q=0.01");//添加请求header
CloseableHttpResponse response = httpClient.execute(httpGet);//执行http请求

    2.2 POST请求例子

String url = "https://ssl.qqlogin.com";
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("Accept", "/*");
httpPost.setEntity(postDataEntity);//添加post请求参数,常用的有StringEntity和UrlEncodedFormatEntity
CloseableHttpResponse response = httpClient.execute(httpPost);

3 处理请求返回结果

String responseBody = EntityUtils.toString(entity,"utf-8");//返回的结果转换字符串,请求图片后使用EntityUtils.toByteArray(entity)转换为字节数组,在存为图片
EntityUtils.consume(entity);//非常重要,释放此次请求的连接

4 关闭httpClient

httpClient.close();//不在使用httpClient时,手动释放连接

三、其他

    HttpClient的强大之处远远不止于此,我们还可以对cookie,响应头做更多的操作;底层源码的cookie校验比较严格,常会导致cookie rejection的警告,有时候需要重写cookie校验工厂类;如果不信任所有连接,并且绕过证书安全检测,请求部分网站会导javax.net.ssl.SSLHandshakeException 这个异常
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值