天天看點

使用WebMagic爬CSDN上的文章

一、先上代碼

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的基本配置

可以進行的配置項如下:

使用WebMagic爬CSDN上的文章

2、抽取頁面并儲存

例如,我們需要将部落格:下的所有文章清單的url都爬出來,用WebMagic如何來實作了?

使用WebMagic爬CSDN上的文章

實作一:使用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:

使用WebMagic爬CSDN上的文章

下面我們來自定義一個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進行分布式管理。如下:

使用WebMagic爬CSDN上的文章

三、爬蟲結果

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都爬出來了。