nul*_*ull 6 html python 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-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>
Run Code Online (Sandbox Code Playgroud)
我希望<div id="content">
在Scrapy 中使用XPath 获取所有文本,但不包括<div class="infobox">
内容,因此预期结果如下:
Title 1
Sub-Title 1
Descripton 1.
Descripton 2.
Sub-Title 2
Descripton 1.
Descripton 2.
Run Code Online (Sandbox Code Playgroud)
但是我还没有到达排除部分,我仍然在努力从中获取文本<div id="content">
.
我试过这个:
response.xpath('//*[@id="content"]/text()').extract()
Run Code Online (Sandbox Code Playgroud)
但它只返回Description 1.
并Description 2.
从两个子标题返回.
然后我尝试了:
response.xpath('//*[@id="content"]//*/text()').extract()
Run Code Online (Sandbox Code Playgroud)
它只返回Title 1
,Sub-Title 1
,Sub-Title 2
,Information Title
,和Long Information Text
.
所以这里有两个问题:
content
div 获得所有的孩子文本?infobox
从选择中排除div?Mat*_*ler 13
使用descendant::
轴查找后代文本节点,并明确声明这些文本节点的父节点不能是div[@class='infobox']
元素.
将上述内容转换为XPath表达式:
//div[@id = 'content']/descendant::text()[not(parent::div/@class='infobox')]
Run Code Online (Sandbox Code Playgroud)
然后,结果类似于(我使用在线XPath工具测试)以下内容.如您所见,文本内容div[@class='infobox']
不再出现在结果中.
-----------------------
Title 1
-----------------------
-----------------------
Sub-Title 1
-----------------------
-----------------------
Description 1.
-----------------------
Description 2.
-----------------------
-----------------------
Sub-Title 2
-----------------------
-----------------------
Description 1
-----------------------
Description 2
-----------------------
-----------------------
-----------------------
Run Code Online (Sandbox Code Playgroud)
你的方法有什么问题?
你的第一次尝试:
//*[@id="content"]/text()
Run Code Online (Sandbox Code Playgroud)
用简单的英语表示:
div
在文档中的任何位置查找具有属性的任何元素(不一定是a )@id
,其值为"content".对于此元素,返回其所有直接子文本节点.
问题:您丢失的文本节点不是外部的直接子节点div
,因为它们位于其子元素内div
.
你的第二次尝试:
//*[@id="content"]//*/text()
Run Code Online (Sandbox Code Playgroud)
翻译为:
div
在文档中的任何位置查找具有属性的任何元素(不一定是a )@id
,其值为"content".对于此元素,查找任何后代元素节点并返回该后代元素的所有文本节点.
问题:您正在丢失直接子文本节点div
,因为您只查看作为子元素的子节点的文本节点div
.
编辑:
回应你的评论:
//div[@id = 'content']/descendant::text()[not(ancestor::div/@class='infobox')]
Run Code Online (Sandbox Code Playgroud)
对于您将来的问题,请确保您显示的HTML 代表您的实际问题.