Python 如何选择所有子文本,但不包括带有Scapy XPath的标记?
我有这个html:Python 如何选择所有子文本,但不包括带有Scapy XPath的标记?,python,html,xpath,scrapy,Python,Html,Xpath,Scrapy,我有这个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-Ti
<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>
但是我还没有到达排除部分,我仍然在努力从文章中抓取文本
我试过这个:
response.xpath('//*[@id="content"]/text()').extract()
但它只返回描述1。和说明2。从两个子标题
然后我试着:
response.xpath('//*[@id="content"]//*/text()').extract()
它只返回标题1、子标题1、子标题2、信息标题和长信息文本
这里有两个问题:
如何从content div获取所有儿童文本?
如何从选择中排除infobox div?
使用substant::axis查找子体文本节点,并明确声明这些文本节点的父节点不能是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的元素,该元素具有属性@id,其值为content。对于此元素,返回其所有直接子文本节点
问题:您正在丢失不是外部div的直接子级的文本节点,因为它们位于该div的子元素内
您的第二次尝试:
//*[@id="content"]//*/text()
翻译为:
查找文档中任何不一定是div的元素,该元素具有属性@id,其值为content。对于该元素,查找任何子元素节点并返回该子元素的所有文本节点
问题:您正在丢失div的直接子文本节点,因为您只查看作为div的后代元素的子元素的文本节点
编辑:
回应你的评论:
//div[@id = 'content']/descendant::text()[not(ancestor::div/@class='infobox')]
对于您将来的问题,请确保您显示的HTML能够代表您的实际问题。您好,谢谢您的回答。但是,如果infobox div包含另一个子元素,则排除解决方案不起作用,请参阅上面我编辑的html示例。@suud我已经编辑了我的答案。如果使用祖先::而不是父::,则表达式将忽略信息框中的任何文本,无论它是否位于另一个元素中。谢谢,这解决了我的问题。我需要的是//div[@class=body]/genderant::text[notancestor::script]举个例子问:在genderant之前放两个斜杠而不是一个斜杠有区别吗?@ilius这两个斜杠//是genderant或self::axis的缩写。如果您的意思是//div[@id='content']//genderant::text[notancestor::div/@class='infobox'],则不会有什么区别,但//or genderant::是多余的。
//div[@id = 'content']/descendant::text()[not(ancestor::div/@class='infobox')]