[Java爬蟲-WebMagic]-05-多級爬取

多級爬取

有時候我們需要爬取一些多級的資料

例如 我想爬取博客 所有分欄所有博文 這樣的話單純的像之前的爬取方法爬不到

而且分欄是可以改變的 可能作者突然加了個分欄,你的程序就需要做一次修改

爲了解決這種問題,所以可以使用 多次爬取來解決


第一步 配置爬蟲入口

這裏直接使用簡寫方式了

//只需要在這裏添加上博客地址就可以了
private static String homeUrl = "https://blog.csdn.net/qq_18604209";

public static void main(String[] args) {
    Spider.create(new MoreProcessor()).addUrl(homeUrl).thread(5).run();
}

第二步 配置模型

我們需要一個數據類型來存放我們爬取的結果

這裏創建了一個Item類,用來表示爬取的數據

class Item{
    private String title;//分欄標題
    private String itemurl;//分欄url
    private Map<String,String> items;//分欄的博文 <標題,鏈接>

	public String getTitle() {
        return title;
    }

    public void setItems(Map<String, String> items) {
        this.items = items;
    }

    public Map<String, String> getItems() {
        return items;
    }
    
    //創建構造方法
    public Item(String title, String itemurl, Map<String, String> items) {
        this.title = title;
        this.itemurl = itemurl;
        this.items = items;
    }

    //轉換成String
    @Override
    public String toString() {
        return "Item{" +
                "title='" + title + '\'' +
                ", itemurl='" + itemurl + '\'' +
                ", items=" + items +
                '}';
    }
}

第三步 配置Site

這裏也簡寫了,Site都有默認配置,這裏直接使用

@Override
public Site getSite() {
    return Site.me();
}

第四步 分析Html

我們把最開始初步的分析Html源碼,找到我們想要的結果

@Override
public void process(Page page) {
    System.out.println(page.getHtml());
}

然後分析控制檯輸出的結果
在這裏插入圖片描述
然後我們就可以先對程序進行一次修改,再進一步分析

分析關鍵字眼

<span class="text">OpenCV學習日記-Java語言描述</span><a class="clearfix" data-report-click="{&quo...}" href="https://blog.csdn.net/qq_18604209/category_9674847.html">

雖然這個a標籤好長,但是還是可以看見href屬性
我們對他進行提取

之後對源碼進行一次修改

@Override
public void process(Page page) {
//   System.out.println(page.getHtml());
    Selectable aside = page.getHtml().$("#asideCategory");//選擇class爲aside-content的
    Selectable title = aside.$(".text","text");//提取class=text 的內容
    Selectable title_url = aside.$(".clearfix","href");//提取class=clearfix 的href屬性

    System.out.println(title.all());
    System.out.println(title_url.all());
}

輸出結果也是我們想要的

[OpenCV學習日記-Java語言描述, OpenCV-Android教程, Java爬蟲-Webmagic,...]
[https://blog.csdn.net/qq_18604209/category_9674847.html, https://blog.csdn.net/qq_18604209/category_9676039.html,...]

第五步 對URL進行分類處理

我們可以使用Request進行二次爬取

而process只有一個,所以我們要對不同的url進行不同的處理

@Override
public void process(Page page) {
    //如果爬取的頁面是首頁
    if (homeUrl.equals(page.getUrl().toString())){
        Selectable aside = page.getHtml().$("#asideCategory");//選擇class爲aside-content的
        Selectable title = aside.$(".text","text");//提取class=text 的內容
        Selectable title_url = aside.$(".clearfix","href");//提取class=clearfix 的href屬性
        
        List<String> titles = title.all();
        List<String> title_urls = title_url.all();

        for (int i = 0; i < titles.size(); i++) {
        Request req =  new Request();
            Item item = new Item(titles.get(i),title_urls.get(i),null);
            req.putExtra("item",item);
            req.setUrl(title_urls.get(i));
            page.addTargetRequest(req);
            page.addTargetRequest("");
        }
        
    }else{//二次爬取的結果
        System.out.println(page.getHtml());
//            同上方法進行結果分析
    }
}

然後在對二次爬取的結果進行分析
這裏就省略分析的過程了

然後從page裏獲取item

Request req = page.getRequest();
Item item = (Item) req.getExtra("item");

再將博文和博文連接封裝成map放到item裏面

List<String> titles = title.all();
List<String> title_urls = title_url.all();

Map<String , String> map = new HashMap<>();
for (int i = 0; i < titles.size(); i++) {
	map.put(titles.get(i),title_urls.get(i));
}

item.setItems(map);

最後抽取我們想要的內容

page.putField(item.getTitle(),item);

因爲默認使用的控制檯輸出,所以程序運行後
最終控制檯輸出

get page: https://blog.csdn.net/qq_18604209/category_9676039.html
OpenCV-Android教程:	Item{title='OpenCV-Android教程', itemurl='https://blog.csdn.net/qq_18604209/category_9676039.html', items={OpenCV-Android教程-Bitmap與Mat對象  =https://blog.csdn.net/qq_18604209/article/details/104044374, OpenCV-Android教程-引言(先看這裏)  =https://blog.csdn.net/qq_18604209/article/details/104033121, OpenCV-Android教程-OpenCV Manager 環境搭建  =https://blog.csdn.net/qq_18604209/article/details/104033262, OpenCV-Android教程-不使用 OpenCV Manager 環境搭建  =https://blog.csdn.net/qq_18604209/article/details/104033944}}
get page: https://blog.csdn.net/qq_18604209/category_9703534.html
Java爬蟲-Webmagic:	Item{title='Java爬蟲-Webmagic', itemurl='https://blog.csdn.net/qq_18604209/category_9703534.html', items={[Java爬蟲-WebMagic]-03-解析Html源碼  =https://blog.csdn.net/qq_18604209/article/details/104213572, [Java爬蟲-WebMagic]-02-獲取網頁源碼  =https://blog.csdn.net/qq_18604209/article/details/104208837, [Java爬蟲-WebMagic]-01-初識爬蟲框架WebMagic  =https://blog.csdn.net/qq_18604209/article/details/104208038, [Java爬蟲-WebMagic]-04-處理爬取的結果  =https://blog.csdn.net/qq_18604209/article/details/104221544}}
...

一個完整的代碼

import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Selectable;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MoreProcessor implements PageProcessor {


    @Override
    public void process(Page page) {
        //如果爬取的頁面是首頁
        if (homeUrl.equals(page.getUrl().toString())){
            Selectable aside = page.getHtml().$("#asideCategory");//選擇class爲aside-content的
            Selectable title = aside.$(".text","text");//提取class=text 的內容
            Selectable title_url = aside.$(".clearfix","href");//提取class=clearfix 的href屬性

            List<String> titles = title.all();
            List<String> title_urls = title_url.all();

            for (int i = 0; i < titles.size(); i++) {
                Request req =  new Request();
                Item item = new Item(titles.get(i),title_urls.get(i),null);
                req.putExtra("item",item);
                req.setUrl(title_urls.get(i));
                page.addTargetRequest(req);
                page.addTargetRequest("");
            }


        }else{//二次爬取的結果
            Selectable column = page.getHtml().$("#column").$(".column_article_list");
            Selectable title = column.$(".title","text");
            Selectable title_url = column.$("a","href");

//			從Request獲取item
            Request req = page.getRequest();
            Item item = (Item) req.getExtra("item");

            List<String> titles = title.all();
            List<String> title_urls = title_url.all();

            Map<String , String> map = new HashMap<>();
            for (int i = 0; i < titles.size(); i++) {
                map.put(titles.get(i),title_urls.get(i));
            }
            item.setItems(map);
            page.putField(item.getTitle(),item);
        }

    }

    @Override
    public Site getSite() {
        return Site.me();
    }

    private static String homeUrl = "https://blog.csdn.net/qq_18604209";

    public static void main(String[] args) {
        //只需要在這裏添加上博客地址就可以了
        Spider.create(new MoreProcessor()).addUrl(homeUrl).thread(5).run();
    }
}


class Item{
    private String title;//分欄標題
    private String itemurl;//分欄url
    private Map<String,String> items;//分欄的博文 <標題,鏈接>



    //創建構造方法
    public Item(String title, String itemurl, Map<String, String> items) {
        this.title = title;
        this.itemurl = itemurl;
        this.items = items;
    }

    public String getTitle() {
        return title;
    }

    public void setItems(Map<String, String> items) {
        this.items = items;
    }

    public Map<String, String> getItems() {
        return items;
    }

    //轉換成String
    @Override
    public String toString() {
        return "Item{" +
                "title='" + title + '\'' +
                ", itemurl='" + itemurl + '\'' +
                ", items=" + items +
                '}';
    }
}


上一篇[Java爬蟲-WebMagic]-04-處理爬取的結果

下一篇[Java爬蟲-WebMagic]-06-將爬取結果保存成Excel

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章