架构师

您现在的位置是:首页 > 程序人生 > 网络爬虫

网络爬虫

Java爬虫第8课:webmagic抽取元素的三种方式

架构师小跟班 2020-07-16 网络爬虫
3.1.实现PageProcessor3.1.1.抽取元素SelectableWebMagic里主要使用了三种抽取技术:XPath、正则表达式和CSS选择器。另外,对于JSON格式的内容,可使用JsonPath进行解析。1.XPath

3.1.实现PageProcessor

3.1.1.抽取元素Selectable

WebMagic里主要使用了三种抽取技术:XPath、正则表达式和CSS选择器。另外,对于JSON格式的内容,可使用JsonPath进行解析。

1.XPath

以上是获取属性class=mt的div标签,里面的h1标签的内容

text()文本内容

page.getHtml().xpath("//div[@class=mt]/h1/text()")

也可以参考课堂资料的W3School离线手册(2017.03.11版).chm

2.CSS选择器

CSS选择器是与XPath类似的语言。在上一次的课程中,我们已经学习过了Jsoup的选择器,它比XPath写起来要简单一些,但是如果写复杂一点的抽取规则,就相对要麻烦一点。

//获取h2标签内容
page.putField("title1", page.getHtml().css("div.main h2").all());
//获取h2标签的文本内容
page.putField("title2", page.getHtml().css("div.main h2","text").all());
//获取img标签的src链接
page.putField("pic",page.getHtml().css("img.mask_img1","src").all());
//获取a标签的href属性
page.putField("url",page.getHtml().css("div.main ul li").css("a","href").all());

div.mt>h1表示class为mt的div标签下的直接子元素h1标签

page.getHtml().css("div.mt>h1").toString()

可是使用:nth-child(n)选择第几个元素,如下选择第一个元素

page.getHtml().css("div#news_div > ul > li:nth-child(1) a").toString()

注意:需要使用>,就是直接子元素才可以选择第几个元素

3.正则表达式

正则表达式则是一种通用的文本抽取语言。在这里一般用于获取url地址。

正则表达式学习难度要大一些,大家可以参考课堂资料《正则表达式系统教程.CHM》

3.1.2.抽取元素API

Selectable相关的抽取元素链式API是WebMagic的一个核心功能。使用Selectable接口,可以直接完成页面元素的链式抽取,也无需去关心抽取的细节。

在刚才的例子中可以看到,page.getHtml()返回的是一个Html对象,它实现了Selectable接口。这个接口包含的方法分为两类:抽取部分和获取结果部分。

这部分抽取API返回的都是一个Selectable接口,意思是说,是支持链式调用的。例如访问https://www.jd.com/moreSubject.aspx页面

//先获取class为news_div的div
//再获取里面的所有包含文明的元素
List<String> list = page.getHtml()
        .css("div#news_div")
        .regex(".*文明.*").all();

3.1.3.获取结果API

当链式调用结束时,我们一般都想要拿到一个字符串类型的结果。这时候就需要用到获取结果的API了。

我们知道,一条抽取规则,无论是XPath、CSS选择器或者正则表达式,总有可能抽取到多条元素。WebMagic对这些进行了统一,可以通过不同的API获取到一个或者多个元素。

当有多条数据的时候,使用get()和toString()都是获取第一个url地址。

String str = page.getHtml()
        .css("div#news_div")
        .links().regex(".*[0-3]$").toString();
String get = page.getHtml()
        .css("div#news_div")
        .links().regex(".*[0-3]$").get();

测试结果:

这里selectable.toString()采用了toString()这个接口,是为了在输出以及和一些框架结合的时候,更加方便。因为一般情况下,我们都只需要选择一个元素!

selectable.all()则会获取到所有元素。

3.1.4.获取链接

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

下面的例子就是获取https://www.jd.com/moreSubject.aspx这个页面中

所有符合https://www.jd.com/news.\\w+?.*正则表达式的url地址

并将这些链接加入到待抓取的队列中去。

public void process(Page page) {
    page.addTargetRequests(page.getHtml().links()
            .regex("(https://www.jd.com/news.\\w+?.*)").all());
    System.out.println(page.getHtml().css("div.mt>h1").all());
}
public static void main(String[] args) {
    Spider.create(new JobProcessor())
            .addUrl("https://www.jd.com/moreSubject.aspx")
            .run();
}


文章评论