XPATH是在XML中进行元素定位的一种强大工具。在网络爬虫中大量使用。
比如下面的文档:
<table width="98%" cellpadding="3" cellspacing="1" align="center">
<tbody>
<tr>
<td width="90" class="f_b">公司名称:</td>
<td width="260">广州xxx有限公司</td>
<td width="90" class="f_b">公司类型:</td>
<td width="260">个体经营 (服务商)</td>
</tr>
<tr>
<td class="f_b">所 在 地:</td>
<td>广东/广州市</td>
<td class="f_b">公司规模:</td>
<td/>
</tr>
<tr>
<td class="f_b">注册资本:</td>
<td>3000万</td>
<td class="f_b">注册年份:</td>
<td>2004</td>
</tr>
</tbody>
</table>
可以下面的XPATH表达式读取公司名字
//tr[1]/td[2]/text()
对于这种比较好的树形,并且元素有属性值可以利用的文档,XPATH表达式比较好写。但是对于一些比较平的树,在一层中有很多元素,更糟糕的是元素中还没有属性值的文档,定位一个元素就比较困难了。比如下面的文档:
<?xml version="1.0" encoding="utf-8"?>
<form name="Standard" method="POST" action="process_request.php" id="Standard" enctype="multipart/form-data">
<h1>Compact device for low-cost, real-time monitoring of blood coagulation</h1>
<br/>
<h2>Stanford Reference:</h2>
<h3>14-045</h3>
<br/>
<h2>Abstract</h2>
<hr size="1"/>
<div id="wrap">Engineers in Prof. James Harris’ laboratory ...</div>
<br/>
<h3>Applications</h3>
<br/>
<ul>
<li>
<b>Patient monitoring</b>- continuous real-time monitoring of blood proteins related to coagulation, with end-user applications such as heart surgery or dialysis
</li>
<li>
<b>Drug delivery</b>- potential for microfluidic system to be adapted to alter dosage of anti-coagulants or other drugs in response to activity or conditions, such as coronary artery thrombosis
</li>
</ul>
<br/>
<h3>Advantages</h3>
<br/>
<ul>
<li>
<b>Compact and inexpensive:</b>
<ul/>
</li>
<li>on-chip analysis with small, low-cost VCSEL, photodetector and microfluidic chip instead of bulky optics imaging system</li>
<li>external circuit small enough to attach to standard blood tubes</li>
<li>enables treatment at point-of-care</li>
</ul>
<ul>
<li>
<b>Real-time monitoring</b>- microfluidic system enables faster analysis than conventional techniques that typically require at least half an hour for sample preparation and processing
</li>
<li>
<b>Compatible with wireless communication</b>
</li>
<li>
<b>Streamlined data collection and analysis</b>
</li>
</ul>
<br/>
<h3>Innovators & Portfolio</h3>
<br/>
<ul>
<li>James Harris</li>
<li>Meredith Lee</li>
<li>Jelena Levi</li>
<li>James Zehnder</li>
</ul>
<br/>
<h3>Date Released</h3>11/6/2017
<br/>
<br/>
<h3>Licensing Contact</h3>
<br/>Scott Elrod, Associate Director
<br/>650.725.9409 (Business)
<br/>
<a href="mailto:scott.elrod@stanford.edu">Request Info</a>
<br/>
<br/>
</form>
我们想读取发布日期,XPATH应该怎么写呢?同一级的元素太多了,用/form/*[position()=10]这种方法很容易出错。有没有简单一点的方法呢?有,可以利用轴的概念。
下表是轴的一些解释。
轴名称 | 结果 |
---|---|
ancestor | 选取当前节点的所有先辈(父、祖父等)。 |
ancestor-or-self | 选取当前节点的所有先辈(父、祖父等)以及当前节点本身。 |
attribute | 选取当前节点的所有属性。 |
child | 选取当前节点的所有子元素。 |
descendant | 选取当前节点的所有后代元素(子、孙等)。 |
descendant-or-self | 选取当前节点的所有后代元素(子、孙等)以及当前节点本身。 |
following | 选取文档中当前节点的结束标签之后的所有节点。 |
namespace | 选取当前节点的所有命名空间节点。 |
parent | 选取当前节点的父节点。 |
preceding | 选取文档中当前节点的开始标签之前的所有节点。 |
preceding-sibling | 选取当前节点之前的所有同级节点。 |
self | 选取当前节点。 |
我们可以用轴的概念简化定位。比如我们可以用下面的表达式读取应用和优点:
//h3[text()='Applications'] | //h3[text()='Applications']/following-sibling::*[position() < 3] | //h3[text()='Advantages'] | //h3[text()='Advantages']/following-sibling::*[position() < 3]
用下面的表达式读取发明人:
//h3[text()='Innovators & Portfolio']/following-sibling::*[position() = 2]
用下面的表达式读取发布日期:
//h3[text()='Date Released']/following-sibling::node()[position()=1]
这里需要注意:一定要用node(),不要用*。*
不包括文本,注释,指令等节点,如果也要包含这些节点需要用node()函数。
还有一点要注意:preceding-sibling和following-sibling中position()=1的都是最靠近当前节点的那一个,也就是说preceding-sibling是从下往上数,following-sibling是从上往下数。