Java 爬虫框架 webmagic 中三种 HTML&XML 页面信息抽取技术解析 -- Xpath & 正则表达式 & CSS选择器

简介:本文详细介绍了用 Java 爬虫框架 webmagic 爬取网站数据的时候,从下载到的 HTML 页面抽取所需信息的三种技术的使用方法:XPath,正则表达式以及 CSS 选择器。

1、XPath

XPath 是一种在 XML 文件中查找信息的语言,它使用路径表达式来选取 XML 文档中的节点或节点集,XPath 也适用于 HTML。为了对XPath的语法进行讲解,我们以下面的HTML案例作为讲解:

<div class="baidu-div">
  <table class="baidu-table">
    <tr>
      <td class="title">
        <a class="name" href="https://www.baidu.com" >百度</a>
      </td>
      <td class="content">
	<span id="section1">aaaaa</span>
      </td>
    </tr>
    <tr></tr>
  </table>
</div>

1.1 绝对路径与相对路径

XPath 表达式中包含 2 种类型的表达式:相对路径与绝对路径。

首先是绝对路径,绝对路径可以用于直接查找元素,不过弊端就是如果元素路径中有一点儿变动的话,XPath 失效。绝对路径以 “ / ” 开始。

其次是相对路径,相对路径以 " // " 开始,相对路径可以从 XML/HTML DOM 结构的任何位置开始,因此使用相对路径便不需要写很长的 XPath 表达式

我们以 webmagic 框架抽取 HTML 页面的元素为例(此处 page 为封装的 HTML 页面对象),如果我们想获得上面 HTML 文件中 class 属性值为 name 的 a 元素的文本内容,绝对路径写法如下:

String result = page.getHtml().xpath("/div/table/tr[1]/td[1]/a[1]/text()")
result 结果是 “百度”

而相对路径的写法如下:

String result = page.getHtml().xpath("//a[@class='name']/text()")
result 结果是 “百度”

可以看出,对比之下,在 XML/HTML 文档的 DOM 结构很复杂的时候,相对路径写起来比较方便。

1.2 Xpath 简介及常见的基础用法

XPath 中包含 7 种类型的节点,XPath 表达式用于从 XML 文档中选择节点或节点列表。

节点类型 节点描述
root 根节点
element 元素
attribute 属性
text 文本
comment 注释
processing instruction 处理指令
namespace 命名空间

其中,根节点、元素、属性、文本、注释是常见的 XPath 节点类型。下面是从 XML/HTML 文档中选择节点或节点列表的常见表达式。

表达式 用法
nodename 选取 XML 文件中所有名为 nodename 的元素
* 选取当前页面的所有子元素
. 选取当前节点
.. 选取当前节点的父节点
/ 从根节点开始
//node 选择整个文件中的所有 node 元素
nodeA/nodeB 对于每一个 nodeA 节点, 将其子节点中的所有 nodeB 节点添加到匹配结果中
nodeA//nodeB 对于每一个 nodeA 节点, 将其后代节点中的所有 nodeB 节点添加到匹配结果中
@attr 选取属性 attr
@* 选取所有属性
text() 选取节点的文本
last() 选择最后一个节点
node[expr] 选择满足条件表达式 expr 的 node 节点
node[number] 选择第 number 个 node 节点(number 是数字)

下面结合下面的 HTML ,用几个案例来说明 XPath 的用法。

<div class="baidu-div">
  <table class="baidu-table">
    <tr>
      <td>
	<a class="name" href="https://www.baidu.com" value="baidu" >百度</a>
	<a class="name" href="https://www.baidu.com" value="use-baidu" >百度一下</a>
      </td>
      <td class='content'>
	<span>11111</span>
	<span>22222</span>
	<span>33333</span>
      </td>
    </tr>
    <tr></tr>
  </table>
</div>
  • 案例 1
String result = page.getHtml().xpath("//td[@class='content']/span[last()-1]/text()")

查找 class 属性为 content 的 td 元素下的倒数第二个 span 元素的文本内容,结果是:22222

  • 案例 2
String result = page.getHtml().xpath("//table[@class='baidu-table']/tr[1]/td[1]/[a2]/@value")

查找 class 属性为 baidu-table 的 table 元素下的第一个 tr 元素下的第一个 td 元素下的第二个 a 元素的 value属性值,结果为:use-baidu


2、正则表达式&CSS选择器

Webmagic 中用正则表达式抽取元素的函数如下

表达式 用法 示例
regex(String regex) 使用正则表达式进行抽取
replace(String regex, String replacement) 替换内容

关于正则表达式,可以参考:学习正则表达式的简单方法

CSS 选择器是与 XPath 类似的元素抽取方式,它在抽取规则相对简单的时候比 XPath 好用,但是如果写复杂一点的抽取规则,就相对要麻烦一点。其抽取函数如下:

表达式 用法 示例
css(String selector) 功能同$(),使用Css选择器选择

关于CSS表达式,可以参考:CSS 教程

我们根据下面的 HTML 文档,对比一下使用 XPath 、正则表达式和 CSS 选择器抽取元素的区别。

<div class="div-level1">
  <table class="div-coding">
    <thead class="head">
      <span>标题</span>
    </thead>
    <tbody class="body">
      <tr class="tr-first">
	<td><span>编程 coding</span></td>
	<td><span>编程之美</span></td>
      </tr>
      <tr class="tr-second">
	<td><span>Java 语言</p></td>
	<td><span>Python 语言</span></td>
      </tr>
      <tr class="tr-third">
	<td>
	  <p>1111</p>
	</td>
      </tr>
    </tbody>
  </table>
</div>
  • 案例1:抽取 HTML 文档中 <p> 标签中所有的内容
//XPath
String result = page.getHtml().xpath("//tr[@class='tr-third']/td/p/text()").all();

//正则表达式
String result = page.getHtml().regex("<p>(.*)+</p>").all();

//CSS选择器
String result = page.getHtml().css("tr.tr-third td p","text").all();
String result = page.getHtml().$("tr.tr-third td p","text").all();

当然,这几种抽取元素的方法也可以混合使用,这个要根据抽取的页面灵活选择。

个人水平有限,如有错误,欢迎各位朋友在评论区批评指正

posted @ 2022-08-11 21:57  ThinkingOverflow  阅读(590)  评论(0编辑  收藏  举报