Java爬虫-webmagic

来源:互联网 发布:如何把json解析出来 编辑:程序博客网 时间:2024/06/04 23:18

一般来说,一个爬虫包括几个部分:

  • 页面下载:页面下载是一个爬虫的基础。下载页面之后才能进行其他后续操作。
  • 链接提取:一般爬虫都会有一些初始的种子URL,但是这些URL对于爬虫是远远不够的。爬虫在爬页面的时候,需要不断发现新的链接。
  • URL管理:最基础的URL管理,就是对已经爬过的URL和没有爬过的URL做区分,防止重复爬取。
  • 内容分析和持久化:一般来说,我们最终需要的都不是原始的HTML页面。我们需要对爬到的页面进行分析,转化成结构的数据,并存储下来。

对于不同的爬虫,对上面几部分的要求是不一样的。

对于通用型的爬虫,例如搜索引擎蜘蛛,需要对互联网大部分网页无差别的进行抓取。这时候难点就在于页面下载和链接管理上。如果要高效的抓取更多页面,就必须进行更快的下载,同时随着链接数量的增多,需要考虑如果对大规模的链接进行去重和调度,就成了一个很大的问题。一般这些问题都会在大公司在专门的团队去解决。对Java来说,如果你要研究通用爬虫,那么可以看一下heritrix或者nutch。

而垂直型的爬虫要解决的问题则不一样,比如想要爬取一些网站的新闻、博客信息,一般抓取数量要求不是很大,难点则在于如何高效的定制一个爬虫,可以精确的抽取出网页的内容,并保存成结构化的数据。这方面需求很多,webmagic就是为解决这个目的而开发的。

webmagic目前的核心代码都在webmagic-core中,webmagic-samples里一些定制爬虫的例子。



Downloader用于页面下载,Scheduler用于URL管理,Pipeline用于离线分析和持久化,PageProcessor用于链接提取和页面分析。
Spider是整个爬虫的调度框架。

Spider类-核心调度

Spider是爬虫的入口类,Spider的接口调用采用了链式的API设计,其他功能全部通过接口注入Spider实现,下面是启动一个比较复杂的Spider的例子。
<!-- lang: java -->Spider.create(sinaBlogProcessor).scheduler(new FileCacheQueueScheduler("/data/temp/webmagic/cache/")).pipeline(new FilePipeline()).thread(10).run();

Spider的核心处理流程非常简单,代码如下:
private void processRequest(Request request) {    Page page = downloader.download(request, this);    if (page == null) {        sleep(site.getSleepTime());        return;    }    pageProcessor.process(page);    addRequest(page);    for (Pipeline pipeline : pipelines) {        pipeline.process(page, this);    }    sleep(site.getSleepTime());}

Downloader-页面下载

页面下载是一切爬虫的开始,大部分爬虫都是通过模拟http请求,接收并分析响应来完成。这方面,JDK自带的HttpURLConnection可以满足最简单的需要,而Apache HttpClient(4.0 后整合到HttpCompenent项目中)则是开发复杂爬虫的不二之选。它支持自定义HTTP头(对于爬虫比较有用的就是User-agent、cookie等)、自动redirect、连接复用、cookie保留、设置代理等诸多强大的功能。

webmagic使用了HttpClient 4.2,并封装到HttpClientDownloader。

对于一些Javascript动态加载的网页,仅仅使用http模拟下载工具,并不能取到页面的内容。这方面的思路有两种:一种是抽丝剥茧,分析js的逻辑,再用爬虫去重现它(比如在网页中提取关键数据,再用这些数据去构造Ajax请求,最后直接从响应体获取想要的数据);另一种就是:内置一个浏览器,直接获取最后加载完的页面。这方面,js可以使用PhantomJS,它内部集成了webkit。而Java可以使用Selenium,这是一个非常强大的浏览器模拟工具。考虑以后将它整理成一个独立的Downloader,集成到webmagic中服从。

PageProcessor-页面分析和链接抽取 

这里说的页面分析主要提HTML页面的分析。页面分析可以说是垂直爬虫中最复杂的一部分,在webmagic里,PageProcessor是定制爬虫的核心。通过编写一个实现PageProcessor接口的类,就可以定制一个自己的爬虫。

页面抽取最基三的方式是使用正则表达式。正则表达式好处是非常通用,解析文本的功能也很强大。但是正则表达式最大的问题是,不能真正对HTML进行语法级别的解析,没有办法处理关系到HTML结构的情况(例如处理标签嵌套)。

HTML分析是一个比较复杂的工作,Java主要有同款分析工具:

(1)HtmlParser
这个项目很久没有维护了,最新版本是2.1.HtmlParser的核心元素是Node,对应一个HTML标签,支持getChildren()等树状遍历方式。HtmlParser另一个核心元素是NodeFiler,通过实现NodeFilter接口,可以对页面元素进行筛选。
(2)Apache tika

专为抽取而生的工具,还支持pdf、zip甚至Java Class。使用tika分析HTML,需要自定一个抽取内容的Handler并继承org.xml.sax.helpers.DefaultHandler,解析方式就是xml标准的方式。
(3)HtmlCleaner和XPath
HtmlCleaner最大优点是:支持XPath的方式选取元素。XPath是一门在XML中查找信息的语言,也可以用XPath与CSS Selector大部分功能都是重合的,但是CSS Selector专门针对HTML,写法更简洁,而XPath则精确到属性值。

webmagic的Selector

Selector是webmagic为了简化页面抽取开发的独立模块,这里整合了CSS Selector、XPath和正则表达式,并可以进行链式的抽取。
例如,我已经下载了一个页面,现在要抽取某个区域的所有包含“blog”的链接,可以这样写:
//content是用别的爬虫工具抽取到的正文String content = "blabla";List<String> links = Html.create(content).$("div.title")  //css 选择,Java里虽然很少有$符号出现,不过貌似$作为方法名是合法的.xpath("//@href")  //提取链接.regex(".*blog.*") //正则匹配过滤.all(); //转换为string列表

Scheduler-URL管理

URL管理的问题可大可小。对于小规模的抓取,URL管理是很简单的。我们只需要将待抓取URL和已抓取URL分开保存,并进行去重即可。因为小规模的URL管理非常简单,很多框架都并不将其抽象为一个模块,而是直接融入到代码中。但是实际上,抽象出Scheduler模块,会使得框架的解耦程序上升一个档次,并非常容易进行横向扩展。

URL去重也是一个比较复杂的问题,如果数据量少,则使用hash的方式就能很好解决,数据量较大的情况下,可以使用BloomFilter或者更复杂的方式。


Pipeline-离线处理和持久化

你可以扩展Pipeline来实现抽取结果的持久化,将其保存到你想要保存的地方。

原创粉丝点击