我有这个HTML:
<div id="content">
<h1>Title 1</h1><br><br>
<h2>Sub-Title 1</h2>
<br><br>
Description 1.<br><br>Description 2.
<br><br>
<h2>Sub-Title 2</h2>
<br><br>
Description 1<br>Description 2<br>
<br><br>
<div class="infobox">
<font style="color:#000000"><b>Information Title</b></font>
<br><br>Long Information Text
</div>
</div>
我希望在<div id="content">
中使用Scath中的XPath获取所有文本,但不包括<div class="infobox">
的内容,因此预期结果如下:
Title 1
Sub-Title 1
Descripton 1.
Descripton 2.
Sub-Title 2
Descripton 1.
Descripton 2.
但是我还没有到达排除部分,我仍然在努力从<div id="content">
获取文本。
我试过这个:
response.xpath('//*[@id="content"]/text()').extract()
但它只返回子标题中的Description 1.
和Description 2.
。
然后我尝试了:
response.xpath('//*[@id="content"]//*/text()').extract()
它只返回Title 1
,Sub-Title 1
,Sub-Title 2
,Information Title
和Long Information Text
。
所以这里有两个问题:
content
div?infobox
div?答案 0 :(得分:12)
使用descendant::
轴查找后代文本节点,并明确声明这些文本节点的父节点不能是div[@class='infobox']
元素。
将上述内容转换为XPath表达式:
//div[@id = 'content']/descendant::text()[not(parent::div/@class='infobox')]
然后,结果类似于(我使用在线XPath工具测试)以下内容。正如您所看到的,div[@class='infobox']
的文字内容不再出现在结果中。
-----------------------
Title 1
-----------------------
-----------------------
Sub-Title 1
-----------------------
-----------------------
Description 1.
-----------------------
Description 2.
-----------------------
-----------------------
Sub-Title 2
-----------------------
-----------------------
Description 1
-----------------------
Description 2
-----------------------
-----------------------
-----------------------
您的方法出了什么问题?
您的第一次尝试:
//*[@id="content"]/text()
用简单的英语表示:
在文档中的任何位置查找具有属性
div
,其值为&#34;内容&#34;的任何元素(不一定是@id
)。对于此元素,返回其所有直接子文本节点。
问题:您丢失的文本节点不是外部div
的直接子节点,因为它们位于div
的子元素内。
你的第二次尝试:
//*[@id="content"]//*/text()
转换为:
在文档中的任何位置查找具有属性
div
,其值为&#34;内容&#34;的任何元素(不一定是@id
)。对于此元素,查找任何后代元素节点并返回该后代元素的所有文本节点。
问题:您正在丢失div
的直接子文本节点,因为您只查看作为div
后代元素的子节点的文本节点。
修改强>:
回应你的评论:
//div[@id = 'content']/descendant::text()[not(ancestor::div/@class='infobox')]
对于您将来的问题,请确保您显示的HTML是代表您实际问题。