使用 | Java使用WebMagic 爬取網站

小小又開始學習了,此次跟着項目學習着,須要使用一個相關的爬蟲,這裏使用的是webmagic做爲網站的爬蟲。css

安裝

這裏使用maven進行安裝。
根據maven下載相關的包html

<dependency>
            <groupId>us.codecraft</groupId>
            <artifactId>webmagic-core</artifactId>
            <version>0.7.3</version>
        </dependency>
        <dependency>
            <groupId>us.codecraft</groupId>
            <artifactId>webmagic-extension</artifactId>
            <version>0.7.3</version>
        </dependency>

Hello World

幾乎全部的api的學習,都是從hello world開始的,webmagic也不例外,使用的一樣也是hello world案例。
以爬取sina博文爲例。
複製如下代碼java

package com.example.demo;

import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.processor.PageProcessor;

public class SinaBlogProcessor implements PageProcessor {

  public static final String URL_LIST = "http://blog\\.sina\\.com\\.cn/s/articlelist_1487828712_0_\\d+\\.html";

  public static final String URL_POST = "http://blog\\.sina\\.com\\.cn/s/blog_\\w+\\.html";

  private Site site = Site
          .me()
          .setDomain("blog.sina.com.cn")
          .setSleepTime(3000)
          .setUserAgent(
                  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31");

  @Override
  public void process(Page page) {
    //列表頁
    if (page.getUrl().regex(URL_LIST).match()) {
      page.addTargetRequests(page.getHtml().xpath("//div[@class=\"articleList\"]").links().regex(URL_POST).all());
      page.addTargetRequests(page.getHtml().links().regex(URL_LIST).all());
      //文章頁
    } else {
      page.putField("title", page.getHtml().xpath("//div[@class='articalTitle']/h2"));
      page.putField("content", page.getHtml().xpath("//div[@id='articlebody']//div[@class='articalContent']"));
      page.putField("date",
              page.getHtml().xpath("//div[@id='articlebody']//span[@class='time SG_txtc']").regex("\\((.*)\\)"));
    }
  }

  @Override
  public Site getSite() {
    return site;
  }

  public static void main(String[] args) {
    Spider.create(new SinaBlogProcessor()).addUrl("http://blog.sina.com.cn/s/articlelist_1487828712_0_1.html")
            .run();
  }
}

查看相關運行結果git

這裏就等於說已經運行成功,爬取到了一些數據github

PageProcessor

這裏用於實現相關的配置。web

代碼以下api

public class GithubRepoPageProcessor implements PageProcessor {

    // 部分一:抓取網站的相關配置,包括編碼、抓取間隔、重試次數等
    private Site site = Site.me().setRetryTimes(3).setSleepTime(1000);

    @Override
    // process是定製爬蟲邏輯的核心接口,在這裏編寫抽取邏輯
    public void process(Page page) {
        // 部分二:定義如何抽取頁面信息,並保存下來
        page.putField("author", page.getUrl().regex("https://github\\.com/(\\w+)/.*").toString());
        page.putField("name", page.getHtml().xpath("//h1[@class='entry-title public']/strong/a/text()").toString());
        if (page.getResultItems().get("name") == null) {
            //skip this page
            page.setSkip(true);
        }
        page.putField("readme", page.getHtml().xpath("//div[@id='readme']/tidyText()"));

        // 部分三:從頁面發現後續的url地址來抓取
        page.addTargetRequests(page.getHtml().links().regex("(https://github\\.com/[\\w\\-]+/[\\w\\-]+)").all());
    }

    @Override
    public Site getSite() {
        return site;
    }

    public static void main(String[] args) {

        Spider.create(new GithubRepoPageProcessor())
                //從"https://github.com/code4craft"開始抓
                .addUrl("https://github.com/code4craft")
                //開啓5個線程抓取
                .thread(5)
                //啓動爬蟲
                .run();
    }
}

抽取元素

這裏使用相關的方法抽取元素。maven

這裏使用相關的方法抽取相關的元素
List<String> urls = page.getHtml().css("div.pagination").links().regex(".*/search/\?l=java.*").all();

保存結果

這裏保存結果使用Pipeline方法ide

public static void main(String[] args) {
    Spider.create(new GithubRepoPageProcessor())
            //從"https://github.com/code4craft"開始抓
            .addUrl("https://github.com/code4craft")
            .addPipeline(new JsonFilePipeline("D:\\webmagic\\"))
            //開啓5個線程抓取
            .thread(5)
            //啓動爬蟲
            .run();
}

實際案例

這裏以 http://blog.sina.com.cn/flash... 做爲例子,在這個例子裏,要從最終的博客文章頁面,抓取博客的標題,內容,和日期。學習

列表頁

列表頁的格式爲 http://blog.sina.com.cn/s/art... 這裏0和1都是可變的頁數。

文章頁

文章頁的格式是,http://blog.sina.com.cn/s/blo... 這裏,最後一段是可變的字符串,爲文章的id

進行正則匹配

這裏用兩個正則進行匹配。
這裏用,xpath//div[@class=\"articleList\"] 進行相關的匹配,

因此,能夠這樣進行匹配

page.addTargetRequests(page.getHtml().xpath("//div[@class=\"articleList\"]").links().regex("http://blog\\.sina\\.com\\.cn/s/blog_\\w+\\.html").all());
page.addTargetRequests(page.getHtml().links().regex("http://blog\\.sina\\.com\\.cn/s/articlelist_1487828712_0_\\d+\\.html").all());

內容的添加

這裏再進行一次內容的添加

page.putField("title", page.getHtml().xpath("//div[@class='articalTitle']/h2"));
page.putField("content", page.getHtml().xpath("//div[@id='articlebody']//div[@class='articalContent']"));
page.putField("date",
        page.getHtml().xpath("//div[@id='articlebody']//span[@class='time SG_txtc']").regex("\\((.*)\\)"));

區分列表和目標頁

這裏,進行區分列表頁,和目標頁。

//列表頁
if (page.getUrl().regex(URL_LIST).match()) {
    page.addTargetRequests(page.getHtml().xpath("//div[@class=\"articleList\"]").links().regex(URL_POST).all());
    page.addTargetRequests(page.getHtml().links().regex(URL_LIST).all());
    //文章頁
} else {
    page.putField("title", page.getHtml().xpath("//div[@class='articalTitle']/h2"));
    page.putField("content", page.getHtml().xpath("//div[@id='articlebody']//div[@class='articalContent']"));
    page.putField("date",
            page.getHtml().xpath("//div[@id='articlebody']//span[@class='time SG_txtc']").regex("\\((.*)\\)"));
}

這樣就完成了最基本例子的讀取。

相關文章
相關標籤/搜索