Нежадный XPATH для получения HTML перед ближайшим узлом h2 - PullRequest
0 голосов
/ 15 декабря 2018

Можно ли скрести XPATH без жадности?Я имею в виду, например, у меня есть этот HTML:

<div>
    <p>A</p>
    <p>B</p>
    <h2>Only until this node</h2>
    <p>I should not get this</p>
    <h2>Even though this node exists</h2>
</div>

Я хочу XPATH, который получает только абзацы с A и B внутри.Текст внутри ближайшего узла h2 всегда меняется, поэтому мне нужен не жадный XPATH, если это возможно.Является ли это возможным?И как?

Ответы [ 3 ]

0 голосов
/ 15 декабря 2018

Попробуйте xpath

//div/p[following::h2[contains(.,'Only until this node')]]

, чтобы получить желаемый контент из элементов html, пока он не достигнет элемента p, содержащего этот текст Only until this node.

Проверьте приведенный ниже пример:

from scrapy import Selector

htmldoc="""
<div>
    <p>A</p>
    <p>B</p>
    <p>C</p>
    <p>D</p>
    <h2>Only until this node</h2>
    <p>E</p>
    <p>F</p>
    <p>I should not get this</p>
    <h2>Even though this node exists</h2>
    <p>I should not even this</p>
</div>
"""
sel = Selector(text=htmldoc)
for item in sel.xpath("//div/p[following::h2[contains(.,'Only until this node')]]/text()").extract():
    print(item)

Что он производит:

A
B
C
D
0 голосов
/ 16 декабря 2018

Я полагаю, <h2>Only until this node</h2> является динамическим, вы можете выбрать первый индекс h2

//div/h2[1]/preceding-sibling::p

var htmlString = `
<body>
  <div>
    <p>A</p>
    <p>B</p>
    <h2>Only until this node</h2>
    <p>I should not get this</p>
    <h2>Even though this node exists</h2>
  </div>
  <div>
    <p>A1</p>
    <p>B2</p>
    <p>C3</p>
    <h2>Second Only until this node</h2>
    <p>I should not get this</p>
    <h2>Even though this node exists</h2>
  </div>
</body>`;

var doc = new DOMParser().parseFromString(htmlString, 'text/xml');
var iterator = doc.evaluate('//div/h2[1]/preceding-sibling::p', doc, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null);
var thisNode = iterator.iterateNext();
while (thisNode) {
  console.log(thisNode.outerHTML);
  thisNode = iterator.iterateNext();
}
0 голосов
/ 15 декабря 2018

Вы можете попробовать следующее выражение XPath-1.0:

/div/p[following-sibling::*[self::h2='Only until this node']]

Получает все p элементы, которые имеют преемник h2 со значением text() "Только до этого узла".

...