考虑以下 html
<div id="relevantID">
<div class="column left">
<h1> Section-Header-1 </h1>
<ul>
<li>item1a</li>
<li>item1b</li>
<li>item1c</li>
<li>item1d</li>
</ul>
</div>
<div class="column">
<ul> <!-- Pay attention here -->
<li>item1e</li>
<li>item1f</li>
</ul>
<h1> Section-Header-2 </h1>
<ul>
<li>item2a</li>
<li>item2b</li>
<li>item2c</li>
<li>item2d</li>
</ul>
</div>
<div class="column right">
<h1> Section-Header-3 </h1>
<ul>
<li>item3a</li>
<li>item3b</li>
<li>item3c</li>
<li>item3d</li>
</ul>
</div>
</div>
我的目标是提取每个节标题的项目。然而,不方便的是,网页设计者决定将数据分成三列,添加一个额外的 div(带有类 column right
等)。
我当前的提取方法是使用 xpath
对于节标题,我使用 xpath(获取具有给定 id 的 div 的所有 h1
元素)
//div[@id="relevantID"]//h1
上面返回一个 h1
元素列表,循环遍历每个元素我应用附加选择器,对于每个匹配的 h1 元素,查找下一个 ul
节点并检索所有它的 li
节点。
following-sibling::ul//li
但是由于设计师的审美,我在 HTML 文件中标记的一种特殊情况下失败了。其中项目分为两个不同的列
div。
我可能可以通过完全删除 column
div 来绕过这个问题,但我不认为修改 html 来使选择器匹配被认为是好的(我还没有看到任何地方需要它)在我到目前为止浏览过的示例中)。
提取这样格式化的数据的好方法是什么?完整的解决方案不是必需的,提示/技巧即可。谢谢!
最佳答案
这些列确实会妨碍使用 following-sibling::
和 preceding-sibling::
,但您可以使用 following::
> 和 preced::
轴(如果列至少使列表项保持正确的文档顺序)。 (您的示例中确实是这种情况。)
以下 XPath 将选择在“Section-Header-1”h1
之后和“Section-Header-2”之前出现的所有 li
项,无论列如何"h1
header 按文档顺序排列:
//div[@id='relevantID']//li[normalize-space(preceding::h1) = 'Section-Header-1'
and normalize-space(following::h1) = 'Section-Header-2']
具体来说,它从示例 HTML 中选择以下项目:
<li>item1a</li>
<li>item1b</li>
<li>item1c</li>
<li>item1d</li>
<li>item1e</li>
<li>item1f</li>
关于xpath - 从分布在不同 div 的列表中提取内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27206092/