访问我的博客

前言

在今年二月份在项目中引入了 WebMagic 技术,用来抓取合作方的书籍,详见之前文章:WebMagic之爬虫监控,这两天新接入了一个合作商,对方接口采取的是 HTTPS 协议,而以前合作商的接口全都是 HTTP 的,在接入这家合作商的时候,发现了问题,只要是 HTTPS 的 URL 全部无法爬取。

一、问题复现

在 WebMagic-core 包中,us.codecraft.webmagic.processor.example.GithubRepoPageProcessor 这个包下面是作者放的示例代码,拷贝这个类代码到新建的类中,右键运行这个类,运行后控制台报出错误:

[WARN ] 2018-05-12 13:28:11,828 download page https://github.com/code4craft error [us.codecraft.webmagic.downloader.HttpClientDownloader.download(HttpClientDownloader.java:91)]

进入这个类,定位到 HttpClientDownloader 源代码 85 行

public Page download(Request request, Task task) {
......
try {
httpResponse = httpClient.execute(requestContext.getHttpUriRequest(), requestContext.getHttpClientContext());
page = handleResponse(request, task.getSite().getCharset(), httpResponse, task);
onSuccess(request);
logger.info("downloading page success {}", request.getUrl());
return page;
} catch (IOException e) {
logger.warn("download page {} error", request.getUrl(), e);
onError(request);
return page;
} finally {
...
}
}

在 85 行此处断点 Debug 运行,发现此行抛出了 SSLException 异常。异常的内容是:

javax.net.ssl.SSLException: Received fatal alert: protocol_version

二、解决问题方法(一)

出现异常后,通过 Google 搜索了一下,找到了 WebMagic 作者黄大的解决方式,详见 Https下无法抓取只支持TLS1.2的站点

于是按照黄大说的方式来做

  1. 首先复制源码中的 HttpClientGeneratorHttpClientDownloader 到自己的项目中。

  2. 修改 HttpClientGenerator 的代码,只需要修改 buildSSLConnectionSocketFactory 这个方法为如下即可。

        ...
    private SSLConnectionSocketFactory buildSSLConnectionSocketFactory() {
    try {
    return new SSLConnectionSocketFactory(createIgnoreVerifySSL(), new String[]{"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();
    }
    ...

    注意: DefaultHostnameVerifier 需要使用 org.apache.http.conn.ssl.DefaultHostnameVerifier,而不要使用 sun.net.www.protocol.https.DefaultHostnameVerifier

  3. 修改 HttpClientDownloader 中引用的 HttpClientGenerator 为你修改后的类。

  4. 设置爬虫 Spider 的 Downloader 为 你修改的 HttpClientDownloader

    Spider.create(new GithubRepoPageProcessor()).setDownloader(new HttpClientDownloader()).addUrl("https://github.com/code4craft").thread(5).run();
  5. 运行后,发现控制台已经可以正常输出所抓取网页的内容了

三、解决问题方法(二)

既然对方接口地址是 HTTPS 的,那我们访问他的 HTTP 接口不就没有这个问题了么?但是事实是,访问对方 HTTP 接口时,会自动跳转到 HTTPS 网址,所以这条路行不通。这时我忽然想到,之前使用 Nginx 解决前端跨域的方法,使用我方的 HTTP 域名,反向代理到对方的 HTTPS 网址是不是就解决了问题呢?于是对 Nginx 进行配置。

server {
listen 80;
server_name partner.domain.com; location / {
proxy_set_header Host github.com;
proxy_pass https://github.com/;
}
}

启动/重启 Nginx,将爬虫的地址由 https://github.com/code4craft 修改为 http://partner.domain.com/code4craft,使用 WebMagic 默认的 Downloader,启动爬虫

public class GithubRepoPageProcessor implements PageProcessor {

    private Site site = Site.me().setRetryTimes(3).setSleepTime(1000).setTimeOut(10000);

    @Override
public void process(Page page) {
System.out.println(page.getRawText());
} @Override
public Site getSite() {
return site;
} public static void main(String[] args) {
Spider.create(new GithubRepoPageProcessor()).addUrl("http://partner.domain.com/code4craft").thread(5).run();
}
}

发现控制台成功打印出了页面的内容,测试中,如果页面,页面的其他请求还是会错误,只有第一个页面是正确的,因此此方法只适合与 Ajax 类似的接口,我们是这样处理抓取 Https 问题的,因为第一种方法对于我们 JDK1.6 项目无效,第一种方法在 JDK 1.8 测试时可以正常抓取的。

后记

如果第一种方法解决不了你的问题,那就跟我一样弄一个临时域名反向代理吧,Nginx 在这方面还是蛮好用的。

解决WebMagic抓HTTPS时出现SSLException的更多相关文章

  1. 解决PHP curl https时error 77(Problem with reading the SSL CA cert (path? access rights?))

    服务器环境为CentOS,php-fpm,使用curl一个https站时失败,打开curl_error,捕获错误:Problem with reading the SSL CA cert (path? ...

  2. fiddler 解决不能抓https包的问题

    新解决方案 重置Fiddler,具体步骤: Tools > Fiddler Options > HTTPS > “Certificates generated by MakeCert ...

  3. Fiddler对https抓包时,提示"HTTPS decryption is disabled."

    安装了fiddlercertmaker.exe 后,对 https://www.baidu.com 进行抓包时,右侧界面提示"HTTPS decryption is disabled.&qu ...

  4. Fiddler对https抓包时,提示"HTTPS decryption is disabled."原因及破解

    Fiddler对https抓包时,提示"HTTPS decryption is disabled." 原因:没有启用 https 解密. 破解: ----------------- ...

  5. fiddler抓包时显示Tunnel to......443是怎么回事

    之前公司的app使用的http协议,因此不需要安装证书也能够转包. 后来改成https协议后,在使用fiddler进行抓包时,一直出现tunnel to 443. 百度了好久也没有具体的解决办法,后来 ...

  6. 【这特么是个坑。。。】iOS 10.3下解决Charles抓包ssl证书信任问题

    针对近期iOS 10.3以上的系统charles抓https信任问题 前言 最近iPhone系统更新到ios 10.3后,在公司里用Charles抓包竟然出现了一些问题,https的请求都会失败,提示 ...

  7. fidder 抓 https包配置方法(ios & android & pc浏览器)

    1. fidder抓https包的基本配置,可参见以下博文 http://blog.csdn.net/idlear/article/details/50999490 2. 遇到问题:抓包看只有Tunn ...

  8. Python 解决Python安装包时提示Unable to find vcvarsall.bat的问题

    解决Python安装包时提示Unable to find vcvarsall.bat的问题   by:授客 QQ:1033553122 问题 Python安装包时,提示Unable to find v ...

  9. [Python] 抓取时光网的电影列表并生成网页

    抓取时光网的电影列表并生成网页 源码 https://github.com/YouXianMing/BeautifulSoup4-WebCralwer 分析 利用BeautifulSoup进行分析网页 ...

随机推荐

  1. BZOJ_3969_[WF2013]Low Power_二分答案

    BZOJ_3969_[WF2013]Low Power_二分答案 Description 有n个机器,每个机器有2个芯片,每个芯片可以放k个电池. 每个芯片能量是k个电池的能量的最小值. 两个芯片的能 ...

  2. apigateway-kong(二)admin-api(结合实例比官网还详细)

    部署好kong之后,则需要将我们自己的接口加入到kong中管理,kong提供了比较全面的restful api,每个版本会有所不同,下面的记录基于kong v0.13.x kong的8001端口是re ...

  3. 七牛云免费对象存储,并绑定到cloudreve中

    之前开通了腾讯云的对象存储COS并使用中,不过之前主要将它当作云盘使用,这两天再做博客系统时发现也可以将它作为网站的图库,这样对网站的访问效率也会提高. 今天了解到七牛云有免费的对象存储可以使用,于是 ...

  4. Boosting(提升方法)之XGBoost

    XGBoost是一个机器学习味道非常浓厚的模型,在数学上非常规范,运用正则化.L2范数.二阶梯度.泰勒公式和分布式计算方法,对GBDT等提升树模型进行优化,不仅能处理更大规模的数据,而且运行效率特别高 ...

  5. 浏览器插件使用socks5代理

    服务端测试,经常会遇到需要通过代理访问的情景,比如公司内网不能访问测试环境,这时可以通过socks5代理来解决. 一.使用Chrome浏览器访问   1. 下载并安装SwitchyOmega插件   ...

  6. 卷积神经网络之VGG

    2014年,牛津大学计算机视觉组(Visual Geometry Group)和Google DeepMind公司的研究员一起研发出了新的深度卷积神经网络:VGGNet,并取得了ILSVRC2014比 ...

  7. Java集合 - List介绍及源码解析

    (源码版本为 JDK 8) 集合类在java.util包中,类型大体可以分为3种:Set.List.Map. JAVA 集合关系(简图) (图片来源网络) List集合和Set集合都是继承Collec ...

  8. arcgis api 4.x for js 离线部署

    在我的GIS之家群里,经常遇到 webgis 开发新手们提问 arcgis api for js 如何本地离线部署,而不是直接调用在线的,因为在线模式依赖互联网以及网速环境因素,受到的限制影响比较大. ...

  9. AndroidStduio3.0 使用gradle将module打包jar文件

    AndroidStduio3.0使用gradle将module打包jar文件,首先需要安装gradle. 打开控制台输入      open -e .bash_profile     命令,就可以打开 ...

  10. 解决Android编译时出现aapt.exe finished with non-zero exit value 1

    当出现这个错误的时候,说明了你的资源文件出错了.然而AS能给你提供的信息实在太少,看了半天没看出个所以然,也没有说明是哪个资源文件出错,一头雾水. 这时候就可以用 Gradlew 来调试. 而grad ...