资讯专栏INFORMATION COLUMN

当年玩耍httpclient

lykops / 414人阅读

摘要:当年玩耍前言是开发中最常用的工具之一,通常大家会使用去调用远程,使用其中比较基础的,长期开发爬虫,会接触不常用的,同时会遇到各式各样的坑,下面会总结这些年遇到的坑坑坑坑一解决过程开发某省份移动爬虫时,加载首页会报标题错误,尝试各种办法都不好

当年玩耍httpclient 前言

httpclient是java开发中最常用的工具之一,通常大家会使用httpcilent去调用远程,使用其中比较基础的api,长期开发爬虫,会接触httpclient不常用的api,同时会遇到各式各样的坑,下面会总结这些年遇到的坑

坑坑坑 一:Received fatal alert: handshake_failure

解决过程

开发某省份移动爬虫时,加载首页会报标题错误,尝试各种办法都不好使,后来发现换了jdk1.8就好使
经过长达一个星期源码探寻,发现错误源头是http在握手时,加密算法不支持导致
jdk1.8以下版本不支持256位( TLS_DHE_RSA_WITH_AES_256_CBC_SHA )

解决方案

1、需要下载jce扩展包 http://www.oracle.com/technet...

2、替换/jre/lib/security/里面的两个jar

3、覆盖后如果报错The jurisdiction policy files are not signed by a trusted signer!,

说明下载的版本不对,要下对应jdk版本的

二:Certificates does not conformto algorithm constraints

解决过程

用mvn打包时报错,
security.cert.CertificateException: Certificates does not conform toalgorithm constraints
原因是在java1.6之后的这个配置文件中,认为MD2的加密方式安全性太低,因而不支持这种加密方式,同时也不支持RSA长度小于1024的密文
需要修改
JAVA_HOME/jre/lib/security/java.security
#jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024

但是这样做需要把每台机器都改一遍,如果新加机器忘记改了,就会发生问题,需要一套方法,只在代码层解决问题

解决方案

经查源码发现了触发问题的代码位置,通过强制继承SSLContextBuilder,并强制把private的keymanagers和trustmanagers的值置空就可以解决这个问题了

static class MySSLContextBuilder extends SSLContextBuilder {
   static final String TLS   = "TLS";
   static final String SSL   = "SSL";
   private String protocol;
   private Set keymanagers;
   private Set trustmanagers;
   private SecureRandom secureRandom;
   public MySSLContextBuilder() {
      super();
      this.keymanagers = new HashSet();
      this.trustmanagers = new HashSet();
   }
}
三:超时时间不生效

解决过程

很多人在使用httpclient时会到网上去找例子,例子中经常会有类似这样的设置
    httpGet.getParams().setParameter(ClientPNames.HANDLE_REDIRECTS, !isAutoRelocal);

使用上面方法时,发送httpclient时,在读取配置时如果发现getParams不为空,则会把以前设置的所有参数都不用了,而使用这里面设置的,所以超时时间会失效

解决方案

request.getParams().setParameter是过期方法,其中每一项参数在RequestConfig里都有对应的,遍历出来替换一遍即可

boolean isRedirect = true;
        if(request != null) {
            HttpParams params = request.getParams();
            if (params instanceof HttpParamsNames) {
                // 暂时只支持这个类型
                isRedirect = params.getBooleanParameter(
                        ClientPNames.HANDLE_REDIRECTS, true);
            }
            // 清空request
            request.setParams(new BasicHttpParams());
        }
        if(timeOut > 0) {
            builder = RequestConfig.custom().setConnectionRequestTimeout(timeOut).setConnectTimeout(timeOut).setSocketTimeout(timeOut).setRedirectsEnabled(isRedirect).setCookieSpec(CookieSpecs.BEST_MATCH);
        } else {
            builder = RequestConfig.custom().setConnectionRequestTimeout(connectionTimeout).setConnectTimeout(connectionTimeout).setRedirectsEnabled(isRedirect).setSocketTimeout(socketTimeout).setCookieSpec(CookieSpecs.BEST_MATCH);
        }
四:fildder监听问题

问题

开发爬虫经常会使用fildder来监控网络请求,但是使用httpclient时想用fildder会很难,网上查各种办法,经常都不好使,
下面为大家来排个错,使用下面方法就可以完美解决这个问题,让fildder监控更容易

解决方案

首先java端
// client builder
HttpClientBuilder builder = HttpClients.custom();
if(useFidder) {
            // 默认fidder写死
            builder.setProxy(new HttpHost("127.0.0.1", 8888));
}
fildder端
tools->fiddler options->https->actions->export root certificate to ... 
inkeytool.exe -import -file C:UsersDesktopFiddlerRoot.cer -keystore FiddlerKeystore -alias Fiddler
五:支持gzip

问题及方案

有些网站返回进行了gzip压缩,返回内容是压缩的结果,需要解压

HttpClient wrappedHttpClient =  builder.setUserAgent(requestUA)
                .addInterceptorLast(new HttpResponseInterceptor() {
                    @Override
                    public void process(HttpResponse httpResponse, HttpContext httpContext) throws HttpException, IOException {
                        HttpEntity httpEntity = httpResponse.getEntity();
                        Header header = httpEntity.getContentEncoding();
                        if (header != null) {
                            for (HeaderElement element : header.getElements()) {
                                if ("gzip".equalsIgnoreCase(element.getName())) {
                                    httpResponse.setEntity(new GzipDecompressingEntity(httpResponse.getEntity()));
                                }
                            }
                        }
                    }
                })
总结
上面一些能想起来的坑,还会遇到很多问题,欢迎来讨论
做一个广告:想简单开发爬虫的欢迎使用uncs

作者:刘鹏飞 宜信技术学院

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/73176.html

相关文章

  • 三年前旧代码的重构、总结与反思

    摘要:最近在维护一个三年前的旧代码,用的是框架。单元测试和语言并发控制实际上是个蛋疼的问题,夸张一点说,当时的并不能特别轻松地实现并发,甚至不能实现并发。语言的功能之一就是自带单元测试。用语言之前,我的习惯是不写单元测试。 最近在维护一个三年前的旧代码,用的是laravel框架。 从某些方面来讲,这个代码算是比较标准为了实现在规定的时间内完成相关功能,同时程序员水平不高、经过大量优化之后,变...

    Shihira 评论0 收藏0
  • 关于降低锁的竞争程度------从奶爸的角度思考

    摘要:关于降低锁的竞争程度从奶爸的角度思考题外话这篇文章的灵感来源于近日带娃耍。具体可参考定律,大致可理解为处理器的利用率与处理器数量和串行比例成反比,此外,在锁上发生竞争,导致上下文切换的开销增加,进而降低程序的性能。 关于降低锁的竞争程度------从奶爸的角度思考 题外话:这篇文章的灵感来源于近日带娃耍。 锁竞争带来的问题 在锁上发生竞争,导致串行操作花费的时间比例增加,进而降低程序...

    YacaToy 评论0 收藏0
  • 小李飞刀:python请与我一起愉快的玩耍吧!

    摘要:属性,可以函数的名字在代码运行期间动态增加功能的方式,称之为装饰器。本质上,就是一个返回函数的高阶函数。比如,定义一个能打印日志的。接受函数作为参数,要放置在函数定义处。一个完整的的代码如下记录的是传入的的值,位置在嵌套内或者带参数的如下。 又是一段叨叨 如果总是担心能不能做到的话,那就干脆不要做了。想做的事情还是一往无前的好,什么都不想,就努力冲冲冲吧! 装饰器 因为函数是一个对象。...

    FuisonDesign 评论0 收藏0
  • HttpClient4.3.x使用-基础篇

    摘要:自定义是请求响应式的,本是无状态的,不过应用通常需要在几个连续的请求之间保持联系,因此可以使用这个来传递变量,注意这个不是线程安全的,建议每个线程使用一个。这个方法是线程安全的,而且可以从任意线程中调用。协议拦截器必须实现为线程安全的。 1、关闭流和response CloseableHttpClient httpclient = HttpClients.createDefault()...

    cartoon 评论0 收藏0
  • Java11 HttpClient小试牛刀

    序 本文主要研究一下Java11的HttpClient的基本使用。 变化 从java9的jdk.incubator.httpclient模块迁移到java.net.http模块,包名由jdk.incubator.http改为java.net.http 原来的诸如HttpResponse.BodyHandler.asString()方法变更为HttpResponse.BodyHandlers.of...

    Bmob 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<