欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java爬虫之HttpClient的使用

程序员文章站 2022-05-05 14:21:42
...

一、简介

    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 这个异常
相关标签: httpClient