选择所有dd标记,直到带有Xpath的新dl标记

时间:2012-05-27 00:09:02

标签: python xpath scrapy

我是一个Scrapy& Xpath初学者,我正在寻找一个具有以下结构的网站

<dl class="ismSummary ismHomeSummary">
        <dt>cat1</dt>
            <dd>value1</dd>
            <dd>value2</dd>
        <dt>cat2</dt>
            <dd>value1</dd>
            <dd>value2</dd>
</dl>

使用Xpath我只想获得value1&amp; cat1的值2(dd

这就是我现在所拥有的

//dt[text()="cat1"]/following-sibling::dd

问题是它不会停留在cat2并继续选择value1&amp;来自cat2的value2。 :(

3 个答案:

答案 0 :(得分:3)

此处的所有节点都是dl的子节点,所以当然所有节点都是第一个dt的兄弟节点,因此当您使用following-sibling时,您可以获得所有节点。

Xpath是用xml制作的,在xml中你可能会有dd个元素作为dt的子元素,但不幸的是,这不是这里的情况。

最简单的方法是只包括dt的所有兄弟(不仅仅是dd s)并迭代结果集直到dt出现。使用Xpath函数可以做同样的事情,但肯定会更复杂。

答案 1 :(得分:3)

使用

//dt[. = 'cat1']
     /following-sibling::dd
       [count(.| //dt[. = 'cat2']/preceding-sibling::dd)
       =
        count(//dt[. = 'cat2']/preceding-sibling::dd)
       ]

假设每个//dt[. = 'cat1']//dt[. = 'cat2']选择一个元素,上面的表达式会精确选择所需的两个dd元素。

基于XSLT的验证

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  <xsl:copy-of select=
  "//dt[. = 'cat1']
     /following-sibling::dd
       [count(.| //dt[. = 'cat2']/preceding-sibling::dd)
       =
        count(//dt[. = 'cat2']/preceding-sibling::dd)
       ]

  "/>
 </xsl:template>
</xsl:stylesheet>

在提供的XML文档上应用此转换时(最后两个dd的值已修改,因此我们确定已选中所需元素):

<dl class="ismSummary ismHomeSummary">
    <dt>cat1</dt>
    <dd>value1</dd>
    <dd>value2</dd>
    <dt>cat2</dt>
    <dd>value3</dd>
    <dd>value4</dd>
</dl>

评估XPath表达式,并将其选择的节点复制到输出中:

<dd>value1</dd>
<dd>value2</dd>

<强>解释

这里我们在XPath 1.0中使用 Kayessian方法进行节点集交集

两个节点集的交集:$ns1$ns2

$ns1[count(.|$ns2) = count($ns2)]

在我们的案例中,我们将$ns1替换为

//dt[. = 'cat1']/following-sibling::dd

,我们将$ns2替换为

//dt[. = 'cat2']/preceding-sibling::dd

答案 2 :(得分:1)

尝试:

rm -Rf MYAPP/migrations/*
python manage.py makemigrations --empty MYAPP
python manage.py makemigrations
python manage.py migrate --fake MYAPP 0002