我是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,我只想获得 cat1 的值 1 和 value2(dd
的)
这就是我现在所拥有的
//dt[text()="cat1"]/following-sibling::dd
问题是它不会停止在 cat2 并继续从 cat2 中选择 value1 和 value2:(。
使用:
//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
这里的所有节点都是dl
的子节点,所以自然都是第一个dt
的兄弟姐妹,所以当你使用following-sibling
时,你会得到它们。
Xpath 是在考虑 xml 的情况下制作的,在 xml 中,您可能会将dd
元素作为 dt
的子元素,但不幸的是,这里的情况并非如此。
最简单的方法是只包括dt
的所有同级(不仅仅是dd
)并遍历结果集,直到出现dt
。使用 Xpath 函数做同样的事情是可能的,但肯定更复杂。
尝试:
dt[text()="cat1"]/following-sibling::dd[preceding-sibling::dt[1]/text()='cat1']