一、先上代碼
import java.util.List;
import org.apache.http.HttpHost;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.scheduler.QueueScheduler;
import us.codecraft.webmagic.scheduler.component.HashSetDuplicateRemover;
public class CSDNPageProcessor implements PageProcessor {
// 爬蟲第一部分,基本配置
private Site site = Site.me().setRetryTimes(3).setSleepTime(1000).setHttpProxy(new HttpHost("xxx.xxx.xx.xx", xxxx));
@Override
public void process(Page page) {
// 爬蟲第二部分,抽取頁面
// 如果不是文章的url位址,則浏覽該頁面下的文章清單的url,并加入TargetRequests中,爬取分頁的url
if(!page.getUrl().regex("http://blog\\.csdn\\.net/liuchuanhong1/article/details.*").match()){
// 抓取文章的url位址
List<String> urls = page.getHtml().xpath("//div[@class='skin_list']").links().regex("http://blog\\.csdn\\.net/.*").all();
// 如果該頁面下存在分頁,則将分頁的url主位址也加入目标請求中
List<String> url2 = page.getHtml().xpath("//div[@class='pagelist']").links().all();
url2.addAll(urls);
page.addTargetRequests(url2);
}else{// 否則,就說明該url是文章的url,則爬出該篇文章對應的具體資訊
CSDNInfo info = new CSDNInfo();
String article = page.getHtml().xpath("//div[@class='skin_m']/div[@class='skin_center']/div[@class='skin_center_t']/div[@class='skin_list']/dl/dd/h3/a/text()").get();
info.setArticleName(article);
page.putField("csdnInfo", info);
}
}
@Override
public Site getSite() {
return site;
}
public static void main(String[] args) {
// 爬蟲第三部分,程式的啟停以及輸出,url去重,線程池大小設定等。
Spider.create(new CSDNPageProcessor()).addUrl("http://blog.csdn.net/liuchuanhong1").addPipeline(new CSDNPipeline()).scheduler(new QueueScheduler().setDuplicateRemover(new HashSetDuplicateRemover())).thread(10).run();
}
}
二、說明
使用WebMagic爬蟲,主要分為3個部分:
1、WebMagic的基本配置
可以進行的配置項如下:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2QvwVe0lmdhJ3ZvwFM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2LcZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39zMwEDN1gzM3EDMzETM2EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
2、抽取頁面并儲存
例如,我們需要将部落格:下的所有文章清單的url都爬出來,用WebMagic如何來實作了?
實作一:使用xpath
如下:
xpath("//div[@class='skin_list']").links().regex("http://blog\\.csdn\\.net/.*").all()
上面這個xpath表示“skin_list”這個div下的所有連結,并進行正則比對,過濾掉不符合條件的連結。
實作二:CSS選擇器
如下:
page.getHtml().css("div.skin_list")
實作三:正規表達式
如下:
page.getHtml().links().regex("http://blog\\.csdn\\.net/.*")
這種方式是将HTML中的所有連結都爬出來,然後進行正則比對,感覺這種方式沒有上面兩種方式好,目的性不是很強。
實作四:JsonPath
這種方式限于json格式的字元串。
有了上面集中方法,我們就可以很輕松的發現連結了。
3、程式的啟停以及輸出,url去重,線程池大小設定等
爬蟲結果的輸出
爬蟲結果的輸出是通過Pipeline來實作的,WebMagic内置了如下集中Pipeline:
下面我們來自定義一個Pipeline,自定義Pipeline很簡單,隻需要實作Pipeline接口即可,代碼如下:
import javax.annotation.Resource;
import us.codecraft.webmagic.ResultItems;
import us.codecraft.webmagic.Task;
import us.codecraft.webmagic.pipeline.Pipeline;
public class CSDNPipeline implements Pipeline {
@Resource(name="csdnInfoDao")
private CSDNInfoDao dao;
@Override
public void process(ResultItems resultItems, Task task) {
// 此處可以存庫,可以輸出到Excel等媒體
CSDNInfo infos = resultItems.get("csdnInfo");
System.out.println("article:"+infos.getArticleName());
dao.save(infos);
}
}
Url去重
在我們爬蟲的過程中,會發現加入TargetRequest的URL會重複,那麼怎麼将重複的URL删掉了,WebMagic已經為我們考慮好了。WebMagic通過Scheduler來實作,WebMagic預設提供了JDK的記憶體隊列來管理URL,并用集合來進行去重。也支援使用Redis進行分布式管理。如下:
三、爬蟲結果
article:Hbase表設計總結
article:讓HBase和Zookeeper分離開來單獨執行
article:spring data hadoop操作hbase
article:redis sentinel部署(Windows下實作)
article:zookeeper叢集環境搭建
article:Kafka環境搭建以及服務封裝
article:spring整合redis sentinel實作redis HA服務調用
article:Camel企業級內建模式--Aggregator
article:Hbase中内置Filter詳解
article:搭建HBase單機環境
article:Spring Bean的初始化和銷毀方式詳解
article:spring整合JMS之異步消息監聽機制
article:Enterprise Architect多人協作方法
article:JMS消息類型
article:spring+ActiveMQ+JMS+線程池實作簡單的分布式,多線程,多任務的異步任務處理系統
article:Jenkins內建Cucumber生成圖形化的測試報告
article:Cucumber中涉及到的類型轉換
article:java中callback回調機制解析
article:jersey+maven建構restful服務--入門篇
article:spring整合JMS一同步收發消息(基于ActiveMQ的實作)
article:使用線程池實作異步打日志和存庫的任務排程
article:storm基礎詳解
article:java中的阻塞隊列
article:Memcache詳解
article:spring data jpa使用詳解
article:Hibernate-validator校驗架構
article:spring 靜态AOP切第三方jar包
article:jdk自帶線程池詳解
從上面的測試結果中可以看出,爬出了所有的文章,連分頁的所有url都爬出來了。