前言
作為Java世界中小白的我(瑟瑟發抖的狀態),在網絡數據抓取這一塊簡直是一無所知.天無絕人之路,這時候我們老大向我推薦一個很好用的爬蟲框架WebCollector,WebCollector是一個無須配置、便于二次開發的JAVA爬蟲框架,它提供精簡的的API,只需少量代碼即可實現一個功能強大的爬蟲。WebCollector-Hadoop是WebCollector的Hadoop版本,支持分布式爬取。WebCollector用起來個人趕腳還是非常的簡單輕便的,這里就以一個初學者的身份簡單分享一下WebCollector.
WebCollector的特點
如果我們使用一個框架,那么我們最需要明白它的優勢和缺點,這樣我們才能更好的發揮它的作用.由于我對網絡數據爬取這一塊現在只了解到WebCollector框架,所以我就從網上找了一些關于WebCollector的資料,然后整理一下.
WebCollector與傳統網絡爬蟲的區別
傳統的網絡爬蟲傾向于整站下載,目的是將網站內容原樣下載到本地,數據的最小單元是單個網頁或文件。而WebCollector可以通過設置爬取策略進行定向采集,并可以抽取網頁中的結構化信息。
WebCollector與HttpClient、Jsoup的區別
WebCollector是爬蟲框架,HttpClient是Http請求組件,Jsoup是網頁解析器(內置了Http請求功能)。
一些程序員在單線程中通過迭代或遞歸的方法調用HttpClient和Jsoup進行數據采集,這樣雖然也可以完成任務,但存在兩個較大的問題:
單線程速度慢,多線程爬蟲的速度遠超單線程爬蟲。
需要自己編寫任務維護機制。這套機制里面包括了URL去重、斷點爬取(即異常中斷處理)等功能。
WebCollector框架自帶了多線程和URL維護,用戶在編寫爬蟲時無需考慮線程池、URL去重和斷點爬取的問題。
WebCollector能夠處理的量級
WebCollector目前有單機版和Hadoop版(WebCollector-Hadoop),單機版能夠處理千萬級別的URL,對于大部分的精數據采集任務,這已經足夠了。WebCollector-Hadoop能夠處理的量級高于單機版,具體數量取決于集群的規模。
WebCollector的遍歷
WebCollector采用一種粗略的廣度遍歷,但這里的遍歷與網站的拓撲樹結構沒有任何關系,用戶不需要在意遍歷的方式。PS:這一點作為小白的我是深有體會...?? ?? ??
網絡爬蟲會在訪問頁面時,從頁面中探索新的URL,繼續爬取。WebCollector為探索新URL提供了兩種機制,自動解析和手動解析。兩種機制的具體內容請讀后面實例中的代碼注釋。
WebCollector的簡單使用
上面說了一堆WebCollector框架的特點,下面我們就簡單的看一下WebCollector在實際過程中是如何使用的呢?
1.首先我們可以直接把WebCollector的jar包導入工程,或者在pom文件中配置Maven依賴關系.如下所示
<dependency>
<groupId>cn.edu.hfut.dmic.webcollector</groupId>
<artifactId>WebCollector</artifactId>
<version>2.70</version>
</dependency>
2. 創建一個實體類繼承于BreadthCrawler類,重寫BreadthCrawler構造器方法.在構造器方法中設置基本爬蟲類屬性.比如設置種子集合、設置URL正則約束、設置是否斷點爬取、設置線程數等等.(代碼在最下面.)
3.搞好構造器方法之后,我們最需要的就是實現接口Visitor中的方法public void visit(Page page, CrawlDatums next)
.在visit這個方法中我們抓取我們所需要的數據信息.
下面我們就拿一個具體的示例來說明WebCollector的抓取過程是如何實現的.我們就要抓取出下面頁面中我的名字"神經騷棟".
我們先創建好類以及構造器和visit方法.如下所示.
package com.infosports.yuqingmanagement.crawler.impl;
import cn.edu.hfut.dmic.webcollector.model.CrawlDatum;
import cn.edu.hfut.dmic.webcollector.model.CrawlDatums;
import cn.edu.hfut.dmic.webcollector.model.Page;
import cn.edu.hfut.dmic.webcollector.plugin.berkeley.BreadthCrawler;
import cn.edu.hfut.dmic.webcollector.util.RegexRule;
public class SaoDongCrawler extends BreadthCrawler {
private final static String crawlPath = "/Users/luying/data/db/jianshu";
private final static String seed = "http://www.lxweimin.com/u/e39da354ce50";
RegexRule regexRule = new RegexRule();
public SaoDongCrawler() {
super(crawlPath, false);
//添加爬取種子,也就是需要爬取的網站地址,以及爬取深度
CrawlDatum datum = new CrawlDatum(seed)
.meta("depth", "1");
addSeed(datum);
//設置線程數,根據自己的需求來搞
setThreads(2);
//添加正則表達式規則
regexRule.addRule("http://.*");
}
@Override
public void visit(Page page, CrawlDatums next) {
}
public static void main(String[] args) throws Exception {
//測試
SaoDongCrawler crawler = new SaoDongCrawler();
crawler.start(2);
}
}
然后我們打開網頁的開發者工具去查找我們所需爬取數據的元素以及class.如下所示
我們通過開發者工具找到了我們所需要的元素,所以我們可以在visit方法里面如下獲取"神經騷棟"四個字.
@Override
public void visit(Page page, CrawlDatums next) {
String name = page.select("a.name").text();
System.out.println(name);
}
或者我們不想獲取標簽的值,只想獲取標簽該如何呢?然后再通過標簽來獲取標簽的值.
@Override
public void visit(Page page, CrawlDatums next) {
Element nameElement = page.select("a.name").first();
String name = nameElement.text();
System.out.println(name);
}
又或者由于某個class的標簽過多,我們需要通過上一級標簽來獲取標簽該如何辦呢?我們需要使用 > 來進行操作.具體示例就拿這個"name"標簽為示例.
@Override
public void visit(Page page, CrawlDatums next) {
Element nameElement = page.select("div.title>a.name").first();
String name = nameElement.text();
System.out.println(name);
}
爬取結果如下所示.
總結
這篇博客寫到這就到了尾聲了,WebCollector基本上可以滿足騷棟我自己的數據爬取需求.當然了,畢竟初學Java不久所以文章很多概念都可能模糊不清,所以如果有錯誤,歡迎指導批評,非常感謝.
本文參考文章:Java開源爬蟲框架WebCollector 2.x入門教程——基本概念