<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中使用它,这是我的第一天。任何帮助表示赞赏!
答案 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