返回介绍

4.2 使用 Selectable 抽取元素

发布于 2019-11-28 05:27:14 字数 3070 浏览 1189 评论 0 收藏 0

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

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

4.2.1 抽取部分 API

方法说明示例
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("\.\*\","")

这部分抽取 API 返回的都是一个 Selectable 接口,意思是说,抽取是支持链式调用的。下面我用一个实例来讲解链式 API 的使用。

例如,我现在要抓取 github 上所有的 Java 项目,这些项目可以在 https://github.com/search?l=Java&p=1&q=stars%3A%3E1&s=stars&type=Repositories 搜索结果中看到。

为了避免抓取范围太宽,我指定只从分页部分抓取链接。这个抓取规则是比较复杂的,我会要怎么写呢?

那么我可以先用 CSS 选择器提取出这个 div,然后在取到所有的链接。为了保险起见,我再使用正则表达式限定一下提取出的 URL 的格式,那么最终的写法是这样子的:

List<String> urls = page.getHtml().css("div.pagination").links().regex(".*/search/\?l=java.*").all();

然后,我们可以把这些 URL 加到抓取列表中去:

List<String> urls = page.getHtml().css("div.pagination").links().regex(".*/search/\?l=java.*").all();
page.addTargetRequests(urls);

是不是比较简单?除了发现链接,Selectable 的链式抽取还可以完成很多工作。我们会在第 9 章示例中再讲到。

4.2.2 获取结果的 API

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

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

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

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

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

好了,到现在为止,在回过头看看 3.1 中的 GithubRepoPageProcessor,可能就觉得更加清晰了吧?指定 main 方法,已经可以看到抓取结果在控制台输出了。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文