[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-处理爬取的结果

发布了47 篇原创文章 · 获赞 44 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_18604209/article/details/104222357