以前总是用的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
想要解决这个问题作者在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查询到网站对于证书的支持情况。
在下面能看到JDK的支持情况:
但是如果你是RSA 2048(SHA256)等,你首先得看带爬取的网站是否支持,然后你把从MySSL中握手成功的方法加到SSLConnectionSocketFactory中。
如果上述操作还是不行,我推荐你打开-Djavax.net.debug=all ,抛出详细的调试信息。
这里感谢,讲得很清楚。里面讲到了3种网上的解决方法,比如jce的安全机制,但是我替换了也无效。
3. Xsoup-XPath解析器
4. 传Cookie,请求头
在site对象后.addCookie和.addHeader,如果你是要添加Cookie,务必加上域名.setDomain,否则不会生效。
5. 剩下的就简单了
开始你自己的表演了,不知道为何WebMagic已经停更了很长一段时间了,很可惜。