使用Selectable抽取元素

[b]使用Selectable抽取元素[/b]

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

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

[b]抽取部分API:[/b]
[table]
|[b]方法[/b]|[b]说明[/b]|[b]示例[/b]|
|xpath(String xpath)|使用XPath选择|html.xpath("//div[@class='title']")|
|$(String selector)|使用Css选择器选择|html.$("div.title")|
|$(String selector,String attr)|使用Css选择器选择|html.$("div.title","text")|
|css(String selector)|功能同$(),使用Css选择器选择|html.css("div.title")|
|links()|选择所有链接|html.links()|
|regex(String regex)|使用正则表达式抽取|html.regex("\(.\*?)\")|
|regex(String regex,int group)|使用正则表达式抽取,并指定捕获组|html.regex("\(.\*?)\",1)|
|replace(String regex, String replacement)|替换内容|html.replace("\","")|
[/table]


[b]获取结果的API:[/b]

当链式调用结束时,我们一般都想要拿到一个字符串类型的结果。这时候就需要用到获取结果的API了。我们知道,一条抽取规则,无论是XPath、CSS选择器或者正则表达式,总有可能抽取到多条元素。WebMagic对这些进行了统一,你可以通过不同的API获取到一个或者多个元素。

[table]
|[b]方法[/b]|[b]说明[/b]|[b]示例[/b]|
|get()|返回一条String类型的结果|String link= html.links().get()|
|toString()|功能同get(),返回一条String类型的结果|String link= html.links().toString()|
|all()|返回一条String类型的结果|List links= html.links().all()|
|match()|是否有匹配结果|if (html.links().match()){ xxx; }|
[/table]


例如,我们知道页面只会有一条结果,那么可以使用selectable.get()或者selectable.toString()拿到这条结果。

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

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


[b]示例代码[/b]


package com.lsiding.msg.page;

import java.util.ArrayList;
import java.util.List;

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

/**
* 建造师列表页面抓取
*
* @author liyixing
*
*/
public class BuilderListPageProcessor implements PageProcessor {
/**
* 部分一:抓取网站的相关配置,包括编码、抓取间隔、重试次数等
*/
private Site site = Site
.me()
.setRetryTimes(3)
.setSleepTime(100)
.setUserAgent(
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36");
/**
* 是否已经获取所有的分页列表
*/
private boolean isAddTargetRequests = false;

/**
* process是定制爬虫逻辑的核心接口,在这里编写抽取逻辑
*/
@Override
public void process(Page page) {
// 部分二:定义如何抽取页面信息,并保存下来
// 姓名
page.putField(
"name",
page.getHtml()
.xpath("//div[@class='addProject']//table//td[2]/a/allText()")
.get());
page.putField(
"click",
"http://location/"
+ page.getHtml()
.xpath("//div[@class='addProject']//table//td[2]/a/@onclick")
.replace("winopen\\('", "")
.replace("',1000,600,'人员证书轨迹查看'\\);", "").get());
// 企业名称
page.putField(
"company",
page.getHtml()
.xpath("//div[@class='addProject']//table//td[3]/tidyText()")
.get());
// 注册编号
page.putField(
"registerNumber",
page.getHtml()
.xpath("//div[@class='addProject']//table//td[4]/tidyText()")
.get());
// 证书编号
page.putField(
"cerNumber",
page.getHtml()
.xpath("//div[@class='addProject']//table//td[5]/tidyText()")
.get());
// 資格證書编号
page.putField(
"qualCerNumber",
page.getHtml()
.xpath("//div[@class='addProject']//table//td[6]/tidyText()")
.get());
// 状态
page.putField(
"status",
page.getHtml()
.xpath("//div[@class='addProject']//table//td[7]/tidyText()")
.get());
// 注册专业
page.putField(
"company",
page.getHtml()
.xpath("//div[@class='addProject']//table//td[8]/tidyText()")
.get());
// 注册有效期
page.putField(
"valTime",
page.getHtml().xpath(
"//div[@class='addProject']//table//td[9]/tidyText()"));

ResultItems resultItems = page.getResultItems();

for (String key : resultItems.getAll().keySet()) {
System.out.println(page.getResultItems().get(key));
}

// 部分三:从页面发现后续的url地址来抓取
if (!isAddTargetRequests) {
// 根据分页数,增加爬取链接
Integer allNumber = Integer
.valueOf(page
.getHtml()
.xpath("//div[@class='paging']//span[@class='localPage'][2]/tidyText()")
.get());

//
List urls = new ArrayList();
// 计算总共有多少页
int pageMaxSize = allNumber / 50;

if (allNumber % 50 != 0) {
pageMaxSize++;
}

for (int x = 2; x <= pageMaxSize; x++) {
urls.add("http://location/outQualificationQuery?pageSize=50&pageIndex="
+ x + "&q_certStatus=0");
}

page.addTargetRequests(urls);
isAddTargetRequests = true;
}
}

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

public static void main(String[] args) {
Spider.create(new BuilderListPageProcessor())
// 从"某个地址再试抓取"开始抓
.addUrl("http://location/outQualificationQuery?pageSize=50&pageIndex=1&q_certStatus=0")
// 开启5个线程抓取
.thread(5)
// 启动爬虫
.run();
}
}

你可能感兴趣的:(webmagic)