Java爬虫框架-WebMagic挖坑补坑指南

以前总是用的Python下的Scrapy和crawley和PHP的小众爬虫框架,最近突然想到了何不用下Java下的框架试试?

查了下Java下的爬虫框架自然也不在少数,Nutch,WebMagic,WebCollector,这三个绝对是够用了,爬一般的网站不在话下,至于遇到那些爬取频次限制,前端JS渲染(AngularJS),各种识别码之类的这都都是爬虫的老问题了,作为成熟的爬虫框架,解决办法应该也是不少的。我觉得现有的爬虫框架都已经很优秀了,本来框架的诞生就是为了解决我们遇到的复杂繁琐的问题,至于爬虫内部的实现还需看代码,认真学习,这些就很多了。

我用的是WebMagic,主要还是看重的如介绍中所说的简单灵活的Java爬虫框架,便于二次开发,提供简单灵活的API,是中国人开发的,文档很详细:http://webmagic.io/docs/zh/

1. Https下无法抓取只支持TLS1.2的站点

你可能会遇到javax.net.ssl.SSLException: Received fatal alert: protocol_version错误。
可以说的是JDK1.8默认使用TLSv1.2 ,JDK1.7默认使用TLSv1.1,WebMagic默认使用的是TLSv1.0。
具体的支持情况可以看oracle的博客:https://blogs.oracle.com/java-platform-group/diagnosing-tls,-ssl,-and-https

oracle的博客中对各个版本的JDK对TLS的说明

想要解决这个问题作者在GitHub上面已经说的很清楚了。Https下无法抓取只支持TLS1.2的站点 #701,作者说在0.7.4版本中会修复这个问题,但是至今都没见到新版本,既然作者已经给出了解决办法,那我们就自己动手就行了。
对于只支持的TLS1.2的站点,需要修改HttpClientGenerator中的buildSSLConnectionSocketFactory方法。

return new SSLConnectionSocketFactory(createIgnoreVerifySSL(), new String[]{"SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2"},
     null,
     new DefaultHostnameVerifier())

我在文章的后面提供了已经修改好了的jar包,你可以替换掉你的,这个问题就能解决,不过我依旧推荐你重写一个Class,编译器会优先加载,buildSSLConnectionSocketFactory方法,这样方便进行调整。(导包的时候不要用oracle的包,用apache的包)

2. Https下无法抓取只支持TLS1.2的站点(同上面)

当你对代码进行了修改后,可能还是会有问题,会遇到SSLHandshakeException: Received fatal alert:handshake_failure
这个问题的出现主要是加密方式的问题。比如你要爬取的网站是RC4(SSL_RSA_WITH_RC4_128_SHA),RSA 2048(SHA256)( TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256)。
你可以通过MySSL查询到网站对于证书的支持情况。
WX20181210-192605.png

在下面能看到JDK的支持情况:
WX20181210-192629.png

如果是RC4,因为JDK8已经停止了对RC4的支持。但是你可以手动启用,https://blog.csdn.net/jiangjun0130/article/details/72190004

但是如果你是RSA 2048(SHA256)等,你首先得看带爬取的网站是否支持,然后你把从MySSL中握手成功的方法加到SSLConnectionSocketFactory中。
WX20181210-191451.png

WX20181210-193244.png

如果上述操作还是不行,我推荐你打开-Djavax.net.debug=all ,抛出详细的调试信息。
这里感谢https://blog.csdn.net/u014644574/article/details/83381303,讲得很清楚。里面讲到了3种网上的解决方法,比如jce的安全机制,但是我替换了也无效。

3. Xsoup-XPath解析器

强大的作者写了个元素抽取器Xsoup。如果使用这个,语法与以往不同,得去看看作者的对照表,里面写得很清楚。http://webmagic.io/docs/zh/posts/ch4-basic-page-processor/xsoup.html

4. 传Cookie,请求头

在site对象后.addCookie.addHeader,如果你是要添加Cookie,务必加上域名.setDomain,否则不会生效。

5. 剩下的就简单了

开始你自己的表演了,不知道为何WebMagic已经停更了很长一段时间了,很可惜。

发表留言

人生在世,错别字在所难免,无需纠正。