一次JAVA爬虫之旅

一次JAVA爬虫之旅

前言

       好早就想做一下爬虫,最近终于完成了。爬了知乎用户信息,现在知乎确实正规了好多,各种反爬虫机制,遇到了不少坑,还好都克服了,现在来记录下这个过程,和把结果展示一下。

准备知识

       我们每天都在浏览网页,如果对其中的某些信息特别感兴趣,我们会选择将其保存下来,但当数据数量很多的时候,我们就会选择用程序来实现这样一个过程,实现自动浏览网页,自动根据我们的要求,保存我们想要的数据。于是,爬虫就应运而生了。所以,简单来说,爬虫就是实现网页自动浏览,数据自动保存,根据我们的需要进行自动化浏览器的操作或者自动化测试的这样一种程序。

HTTP协议

       计算机网络中必学的协议,我们之前已经模拟过web服务器和浏览器,这也需要http基础,理解http协议,然后根据不同的语言去用不同的工具包,模拟http请求,得到响应页面。其中我们要注意的是,要模拟登陆,就要用到cookies等。下图就是一个http响应信息:

前端基础

       要有一定的前端基础,能会分析出请求地址,通过firebug等分析网页元素,我甚至看过一个github项目,通过手机访问和路由器、抓包软件找出了摩拜单车的一些业务请求地址,然后进行爬虫,单车也是最近很流行。比如我用Mac的Safari审查元素如下。需要提出的是,我在爬取网易云音乐或者qq空间的时候,除了分析请求,如果想爬取的信息在iframe中,而iframe是重定向的,这时候也许一些内嵌浏览器就要上场了,比如selenium,需要模拟浏览器行为,得到的是最后页面。

正则表达式

       当我们已经得到了html的响应页面,那么肯定需要筛选出我们想要的信息,这时候我们就需要用到正则表达式了,相关类似的还有XPath、CSS选择器等,可以根据匹配规则筛选信息,也有很多在线网站可以验证我们写的正则表达式的正确性。下图是基本的正则匹配规则。

其他

       一种编程语言,这里我们使用的是java,之后都是java相关的。为了让程序更高效,我们还用到了JUC中的阻塞队列、线程池、原子类、可重入锁等技术,如果要数据持久化的话,我们还要一定的数据库基础,更深层次的可以研究比如:直接下载html网页保存,然后用搜索引擎,比如我看过一个项目使用ElasticSerch保存下载的html网页,ElasticSerch是一个搜索服务器,apache的子项目,或许你知道PageRank,知道谷歌的几大论文,想象百度和谷歌怎么检索那么多网站,并进行相关度排行,爬虫也可以分布式,比如nutch就是一个分布式爬虫的框架。最后数据保存了,还可以使用数据可视化工作,做出比较好看的直观的图表来展现爬取的数据。

相关框架

       python可以用scrapy,java的我使用的是webmagic,还有分布式的nutch等,虽然使用框架,但是对于框架本身我们还要了解一下。这里重点说说webmagic。

webmagic

       首先献上官方文档:WebMagic中文版官方文档

       如上图就是整体框架图,Downloader负责从互联网上下载页面,以便后续处理。WebMagic默认使用了Apache HttpClient作为下载工具。之后我们对比一些java中模拟http请求的工具包。PageProcessor负责解析页面,抽取有用信息,以及发现新的链接。WebMagic使用Jsoup作为HTML解析工具,并基于其开发了解析XPath的工具Xsoup,也就是我们页面信息提取部分。Pipeline负责抽取结果的处理,包括计算、持久化到文件、数据库等。WebMagic默认提供了“输出到控制台”和“保存到文件”两种结果处理方案,根据我们持久化方式也可以自定义。

       webmagic封装了很多api给用户用,而且采用链式api方式,很多方面也许你只需要设置一下。而且如果知识简单的爬虫,自己需要书写的代码也很少。有了基础知识的准备,我们应该再去看看框架的源码,比较一下各种工具,也许更方便我们的使用。

框架工具

       这里我们针对核心包的一些内容学习。我建议每个技术都找些demo运行试试。

如何模拟请求

       源码在downloader包中,WebMagic默认使用了Apache HttpClient作为下载工具。其他的还有URLConnection。一个是开园框架,一个是原生JDK,如果使用后者,我发现登陆功能并不能实现,爬取的网页首先是登陆页面,HttpClient提供api包装请求头。

       首先:在 JDK 的 java.net 包中已经提供了访问 HTTP 协议的基本功能:HttpURLConnection。但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。

       其次:HttpClient是个很不错的开源框架,封装了访问http的请求头,参数,内容体,响应等等,
HttpURLConnection是java的标准类,什么都没封装,用起来太原始,不方便,比如重访问的自定义,以及一些高级功能等。

       HttpClient就是一个增强版的HttpURLConnection,HttpURLConnection可以做的事情HttpClient全部可以做;HttpURLConnection没有提供的有些功能,HttpClient也提供了,但它只是关注于如何发送请求、接收响应,以及管理HTTP连接。

如何筛选信息

       源码再selector包中,源码书写大都用接口,抽象类和实现类,类似JDK源码的书写风格,高扩展性。Jsoup这方面也做得很好,我在代码中也部分直接使用了Jsoup,源码在Jsoup基础上其中分别包装了CSS选择器、正则表达式、Xpath的api使用方法。可以通过相关方法获取页面的链接、但是要准备的定位信息,还是需要一些调试,比如知乎上用户信息的缺省就对程序有一定影响。

数据持久化

       源码在Pipeline何种,提供了输出栏打印、文件保存等实现类。我们采用的是mysql存储,基于JDBC,并没有使用mybatis之类的持久层框架,也没那个必要。

代码结构

       需要特殊说明的是ip代理我是买的,有些是提供免费的,我试过了项目不是很好,购买后,他会给一个api连接,实行更新半个小时左右,相关访问代码也是固定给出的。当然对于针对的ip反爬虫机制,我们可以降低访问频率,经过测试,知乎如果不断访问,半个小时就会down,会封2天左右。

结果

       我最后爬下来的一些数据如下:

       暂时还没有进行可视化分析,有兴趣我可以把数据给你,邮箱:wust_zoujing@foxmail.com。

说明

       文中出现的图片,文字描述有些来自互联网,但是出处无法考究,如果侵犯您的相关权益,请联系我,核实后我会马上加上转载说明。谢谢!!!

坚持原创技术分享,您的支持将鼓励我继续创作!