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();

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

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

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JsoupXpath 是一款纯Java开发的使用xpath解析html解析器,xpath语法分析与执行完全独立,html的DOM树生成借助Jsoup,故命名为JsoupXpath.为了在java里也享受xpath的强大与方便但又苦于找不到一款足够强大的xpath解析器,故开发了JsoupXpath。JsoupXpath的实现逻辑清晰,扩展方便,支持几乎全部常用的xpath语法.http://www.cnblogs.com/ 为例 "//a/@href"; "//div[@id='paging_block']/div/a[text()='Next >']/@href"; "//div[@id='paging_block']/div/a[text()*='Next']/@href"; "//h1/text()"; "//h1/allText()"; "//h1//text()"; "//div/a"; "//div[@id='post_list']/div[position()1000]/div/h3/allText()"; //轴支持 "//div[@id='post_list']/div[self::div/div/div/span[@class='article_view']/a/num()>1000]/div/h3/allText()"; "//div[@id='post_list']/div[2]/div/p/preceding-sibling::h3/allText()"; "//div[@id='post_list']/div[2]/div/p/preceding-sibling::h3/allText()|//div[@id='post_list']/div[1]/div/h3/allText()"; 在这里暂不列出框架间的对比了,但我相信,你们用了会发现JsoupXpath就是目前市面上最强大的的Xpath解析器。 快速开始 如果不方便使用maven,可以直接使用lib下的依赖包跑起来试试,如方便可直接使用如下dependency(已经上传至央maven库,最新版本0.1.1):    cn.wanghaomiao    JsoupXpath    0.1.1 依赖配置好后,就可以使用如下例子进行体验了!String xpath="//div[@id='post_list']/div[./div/div/span[@class='article_view']/a/num()>1000]/div/h3/allText()";String doc = "..."; JXDocument jxDocument = new JXDocument(doc); List<Object> rs = jxDocument.sel(xpath); for (Object o:rs){     if (o instanceof Element){             int index = ((Element) o).siblingIndex();             System.out.println(index);     }     System.out.println(o.toString()); } 其他可以参考 cn.wanghaomiao.example包下的例子 语法 支持标准xpath语法(支持谓语嵌套),支持全部常用函数,支持全部常用轴,去掉了一些标准里面华而不实的函数和轴,下面会具体介绍。语法可以参考http://www.w3school.com.cn/xpath/index.asp 关于使用Xpath的一些注意事项 非常不建议直接粘贴Firefox或chrome里生成的Xpa

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值