Xpath在scrapy 0.24.5中选择两个节点之间的节点

时间:2015-06-24 17:16:38

标签: python html xpath web-scraping scrapy

<h3>Q1</h3>  
<p><p>text1</p></p><a name="1"> </a>  
<p>...</p>  
...  
<ul><li>...</li></ul>
<h3>Q2</h3>  
<p>text2</p><a name="2"> </a>  
<p>...</p>  
...  
<ul><li>...</li></ul>
<h3>Q3</h3>  
<p>text3</p>
<p>...</p>  
...  
<ul><li>...</li></ul>

上面是我的html,我想抓住单个h3的文本和跟随它的节点文本,直到下一个h3。换句话说,如果我将它们放在字典中,结果将如下所示:

{Q1:text1, Q2:text2, Q3:text3}    

我首先尝试选择所有h3标签,然后遍历h3标签列表。对于每个h3标签,我尝试在下一个h3标签之前选择所有节点。这是我的代码:

>>> h3_tags = response.xpath(".//h3")   
>>> for h3_tag in h3_tags:    
>>>     texts = h3_tag.xpath("./following-sibling::node()[count(preceding-sibling::h3)=1]/descendant-or-self::text()").extract()  

但是这只提取了第一个h3标签之后的p文本(除了它还包括第二个h3标签的文本),我没有为其余的h3标签提供任何内容。

如果我使用:

>>> h3_tags = response.xpath(".//h3")   
>>> for h3_tag in h3_tags:    
>>>     texts = h3_tag.xpath("./following-sibling::node()[preceding-sibling::h3]/descendant-or-self::text()").extract()  

我从前一个p获得了第二个和第三个h3的冗余文本。

我在Scrapy 0.24.5中使用它,这是我的第一天。任何帮助表示赞赏!

1 个答案:

答案 0 :(得分:1)

taskBody

的帮助下,您仍然可以使用count(preceding-sibling...)技术
enumerate()

请注意,>>> for cnt, h3 in enumerate(selector.xpath('.//h3'), start=1): ... print h3.xpath('./following-sibling::node()[count(preceding-sibling::h3)=%d]' % cnt).extract() ... [u' \n', u'<p></p>', u'<p>text1</p>', u'<a name="1"> </a>', u' \n', u'<h3>Q2</h3>'] [u' \n', u'<p>text2</p>', u'<a name="2"> </a>', u' \n', u'<h3>Q3</h3>'] [u' \n', u'<p>text3</p>'] >>> >>> for cnt, h3 in enumerate(selector.xpath('.//h3'), start=1): ... print h3.xpath('./following-sibling::node()[count(preceding-sibling::h3)=%d]/descendant-or-self::text()' % cnt).extract() ... [u' \n', u'text1', u' ', u' \n', u'Q2'] [u' \n', u'text2', u' ', u' \n', u'Q3'] [u' \n', u'text3'] >>> 与lxml的效果不佳,在<p><p>text1</p></p>中创建了2个兄弟p而不是p

相关问题