XPath中节点和节点功能的联合

时间:2016-10-04 04:14:17

标签: python xpath scrapy

我正在使用Scrapy抓取一些网页。我想编写一个XPath查询,它将在父<div>内向任何子<a>节点附加几个字符的文本,同时正常提取div的self节点的文本。基本上它就像一个普通的descendant-or-self//查询,只是用|编写并在后代上调用concat函数(如果它们存在,则为{{} 1}}标签)。

这些都返回一个值:

  1. <a>
  2. my_div.xpath('div[@class="my_class"]/text()).extract()
  3. my_div.xpath('concat(\'@\', div[@class="my_class"]/a/text())').extract()
  4. 然而,尝试以(3)的格式组合上述(1)和(2):

    my_div.xpath('div[@class="my_class"]/text() | div[@class="my_class"]/a/text()').extract()

    导致以下错误:

    my_div.xpath('div[@class="my_class"]/text() | concat(\'@\', div[@class="my_class"]/a/text())').extract()

    如何让XPath识别节点与节点上调用的函数的并集?

3 个答案:

答案 0 :(得分:0)

我认为它不起作用,因为concat实际上并没有返回路径,而|用于选择多个路径

  

使用|在XPath表达式中,您可以选择多个路径。

根据http://www.w3schools.com/xsl/xpath_syntax.asp

为什么不将它分成两部分呢?通常,您将ItemLoaders与蜘蛛一起使用。因此,您可以根据需要添加任意数量的路径和/或值。

mil = MyItemLoader(response=response)
mil.add_xpath('name', 'xpath1')
mil.add_xpath('name', 'xpath2')
mil.load_item()
# {'name': ['values_of_xpath1','values_of_xpath2']

如果您想保留树顺序,可以尝试:

nodes = my_div.xpath('div[@class="my_class"]')
text = []
for node in nodes:
    text.append(node.xpath("text()").extract_first())
    text.append(node.xpath("a/text()").extract_first())
text = '@'.join(text)

你可以用列表理解来简化它,但你明白了:提取节点并迭代两个值的节点。

答案 1 :(得分:0)

在XPath 1.0中,location path返回node-setconcat函数返回stringunion operator |计算其操作数的并集,它必须是 node-sets

答案 2 :(得分:0)

更新:这就是我所做的:

item['div_text'] = []
div_nodes = definition.xpath('div[@class="my_class"]/a | div[@class="my_class"]/text()')
for n in div_nodes:
    if n.xpath('self::a'):
        item['div_text'].append("@%s" % n.xpath('text()').extract_first())
    else:
        item['div_text'].append(n.extract())