WebMagic的学习(二)——实现PageProcessor以及爬虫demo

一、爬虫实例

爬取csdn个人主页,先进入主页,我们发现列表页是这样的规则

https://blog\\.csdn\\.net/qq_41061437/article/details/1

只有后面的数字会发生变化,因此可以用正则表达式:

"https://blog\\.csdn\\.net/qq_41061437/article/list/\\d,定义一个URL_LIST:
public static final String URL_LIST = "https://blog\\.csdn\\.net/qq_41061437/article/list/\\d";

单独点击一篇文章,发现URL地址是这样的:https://blog.csdn.net/qq_41061437/article/details/82258431,每一篇文章只有最后的数字会改变,我们可以定义一个URL_POST,后面利用正则表达式来表示:

public static final String URL_POST = "https://blog\\.csdn\\.net/qq_41061437/article/details/\\d{1,}";

定义抓取规则:

private Site site = Site
            .me()
            .setDomain("blog.csdn.net")
            .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");

我们需要先抓取列表页,列表页抓取利用XPath,XPath获取方式如图:

WebMagic的学习(二)——实现PageProcessor以及爬虫demo_第1张图片

然后写规则:

page.addTargetRequests(page.getHtml().xpath("//*[@id=\"mainBox\"]/main/div[2]").links().regex(URL_POST).all());
            page.addTargetRequests(page.getHtml().links().regex(URL_LIST).all());

接着就是抓取文章内容,这里只抓取文章的标题和内容,也是利用XPath来获取,方式同上:

WebMagic的学习(二)——实现PageProcessor以及爬虫demo_第2张图片

现在可以编写规则:
            page.putField("title", page.getHtml().xpath("//*[@id=\"mainBox\"]/main/div[1]/div/div/div[1]/h1"));
            page.putField("content", page.getHtml().xpath("//*[@id=\"article_content\"]"));

接着只需要定义main方法启动就行,目的是利用Spider将各个组件组织起来:

Spider.create(new csdnSpider()).addUrl("https://blog.csdn.net/qq_41061437/article/list/1")
                .run();

完整代码如下:

package com.matai03;

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

public class csdnSpider implements PageProcessor {
    public static final String URL_LIST = "https://blog\\.csdn\\.net/qq_41061437/article/list/\\d";

    public static final String URL_POST = "https://blog\\.csdn\\.net/qq_41061437/article/details/\\d{1,}";
    private Site site = Site
            .me()
            .setDomain("blog.csdn.net")
            .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("//*[@id=\"mainBox\"]/main/div[2]").links().regex(URL_POST).all());
            page.addTargetRequests(page.getHtml().links().regex(URL_LIST).all());
            //文章页
        } else {
            page.putField("title", page.getHtml().xpath("//*[@id=\"mainBox\"]/main/div[1]/div/div/div[1]/h1"));
            page.putField("content", page.getHtml().xpath("//*[@id=\"article_content\"]"));

        }
    }

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

    public static void main(String[] args) {
        Spider.create(new csdnSpider()).addUrl("https://blog.csdn.net/qq_41061437/article/list/1")
                .run();
    }
}

二、页面元素抽取

对于下载到的Html页面,你如何从中抽取到你想要的信息?WebMagic里主要使用了三种抽取技术:XPath、正则表达式和CSS选择器。另外,对于JSON格式的内容,可使用JsonPath进行解析。

①XPath

XPath本来是用于XML中获取元素的一种查询语言,但是用于Html也是比较方便的。例如:

page.getHtml().xpath("//*[@id=\"mainBox\"]/main/div[2]")

这段代码使用了XPath,它的意思是“查找所有id属性为'mainBox'下的mian节点下的第二个div的元素。 对应的Html是这样子的:

WebMagic的学习(二)——实现PageProcessor以及爬虫demo_第3张图片

②CSS选择器

CSS选择器是与XPath类似的语言。如果大家做过前端开发,肯定知道$('h1.entry-title')这种写法的含义。客观的说,它比XPath写起来要简单一些,但是如果写复杂一点的抽取规则,就相对要麻烦一点。

③正则表达式

正则表达式则是一种通用的文本抽取语言。

page.addTargetRequests(page.getHtml().links().regex("(https://github\\.com/\\w+/\\w+)").all());

这段代码就用到了正则表达式,它表示匹配所有"https://github.com/code4craft/webmagic"这样的链接。

④JsonPath

JsonPath是于XPath很类似的一个语言,它用于从Json中快速定位一条内容。WebMagic中使用的JsonPath格式可以参考这里:https://code.google.com/p/json-path/

三、链接的发现

有了处理页面的逻辑,我们的爬虫就接近完工了!

但是现在还有一个问题:一个站点的页面是很多的,一开始我们不可能全部列举出来,于是如何发现后续的链接,是一个爬虫不可缺少的一部分。

page.addTargetRequests(page.getHtml().links().regex("(https://github\\.com/\\w+/\\w+)").all());

这段代码分为两部分,page.getHtml().links().regex("(https://github\\.com/\\w+/\\w+)").all()用于获取所有满足"(https:/ /github\.com/\w+/\w+)"这个正则表达式的链接,page.addTargetRequests()则将这些链接加入到待抓取的队列中去。

 

你可能感兴趣的:(框架及三方组件)