假设我的HTML包含这样的内容,并且我想忽略div
class=log
的{{1}},除非前面有div
class=ts
,在这种情况下我想在某些数据结构中捕获兄弟div
的文本内容。
一个人可以这样做,如果是的话,请问怎么样?
<div class='log'>start</div>
<div class='ts'>2017-03-14</div><div class='log'>note 1</div>
<div class='ts'>2017-03-15</div><div class='log'>note 2</div>
<div class='log'>start</div>
答案 0 :(得分:2)
以下XPath返回带有div
class='log'
的{{1}},其div
前面带有class='ts'
:
//div[@class='log' and preceding-sibling::node()[1][self::div/@class='ts']]
我打破了可能令人困惑的部分:
preceding-sibling::node()[1]
:获取一个直接位于当前上下文元素之前的任何类型的节点(文本,元素,注释等)[self::div/@class='ts']
:验证该节点是div
,class
属性等于'ts'从这里开始,您需要合并主机编程语言以获得所需的结果,例如,在python中使用lxml
:
>>> raw = '''<div>
... <div class='log'>start</div>
... <div class='ts'>2017-03-14</div><div class='log'>note 1</div>
... <div class='ts'>2017-03-15</div><div class='log'>note 2</div>
... <div class='log'>start</div>
... </div>'''
>>> from lxml import html
>>> root = html.fromstring(raw)
>>> query = "//div[@class='log' and preceding-sibling::node()[1][self::div/@class='ts']]"
>>> [[d.getprevious().text, d.text] for d in root.xpath(query)]
[['2017-03-14', 'note 1'], ['2017-03-15', 'note 2']]
以下是将根据请求返回['2017-03-14', 'note 1','2017-03-15', 'note 2']
的XPath:
//div[
(@class='log' and preceding-sibling::node()[1][self::div/@class='ts'])
or
(@class='ts' and following-sibling::node()[1][self::div/@class='log'])
]/text()