webmagic 抓取带有https的网站,抛出的异常javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_fail
程序员文章站
2022-05-02 22:12:59
...
解决思路
在网上找了几种方法,没有解决问题。
-
方法一(试了没解决)
jdk中jce的安全机制导致报的错,按照大家的方式,要去oracle官网下载对应的jce包替换jdk中的jce包。
jce所在地址: %JAVA_HOME%\jre\lib\security里的local_policy.jar,US_export_policy.jar
JDK7 http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
JDK8 http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
-
方法二(可能是我使用有误,也没解决)
在请求连接之前,加上System.setProperty(“https.protocols”, “SSLv3, TLSv1, TLSv1.1, TLSv1.2”); -
方法三(我自己是用这种方式解决的)
首先先确保导入的maven版本(最好使用最新版,出现的问题会少一些)
maven依赖
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-core</artifactId>
<version>0.7.3</version>
</dependency>
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-extension</artifactId>
<version>0.7.3</version>
</dependency>
- 解决方式
- 先到webmagic源码上,复制源码中的 HttpClientGenerator
与 HttpClientDownloader 到自己的项目中。 - 修改 HttpClientGenerator 的代码,需要修改 buildSSLConnectionSocketFactory 这个方法。
private SSLConnectionSocketFactory buildSSLConnectionSocketFactory() {
try {
return new SSLConnectionSocketFactory(createIgnoreVerifySSL(), new String[]{"SSLv2Hello","SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2"},
null,
new DefaultHostnameVerifier()); // 优先绕过安全证书
} catch (KeyManagementException e) {
logger.error("ssl connection fail", e);
} catch (NoSuchAlgorithmException e) {
logger.error("ssl connection fail", e);
}
return SSLConnectionSocketFactory.getSocketFactory();
}
- 修改 HttpClientGenerator 的代码,需要修改createIgnoreVerifySSL这个方法:
private SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException {
// 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法
X509TrustManager trustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
SSLContext sc = SSLContext.getInstance("TLS");//将SSLv3改为TLS,主要是修改这个地方
sc.init(null, new TrustManager[] { trustManager }, null);
return sc;
}
- 修改 HttpClientDownloader 中引用的 HttpClientGenerator 为你修改后的类。
- 设置爬虫 Spider 的 Downloader 为 你修改的 HttpClientDownloader。
Spider spider=Spider.create(new FitnessProcessor());//FitnessProcessor为自己创建的类
gifUrl="https://www.***.com/tool/fuji/";
spider.setDownloader(new HttpClientDownloader()).addUrl(gifUrl).thread(10).run();
- 你可以使用SSL/TLS安全评估去查一下你访问的网址支持哪些协议。我访问的网站只支持TLS 1.2。而且客户端握手模拟 jdk支持1.8,之前一直使用jdk1.7去访问一直不成功。具体的还要看具体网站支持哪些协议。