Запретить lxml выбор следующего текстового узла после соответствующего элемента - PullRequest
1 голос
/ 19 июня 2019

Мне нужно найти <div> с id="XXX" в некотором шаблоне строки HTML:

from lxml import html

template = '''
Text node 1
<div id="XXX">XXX content</div>
Text node 2
'''

tree = html.fromstring(template)
element = tree.get_element_by_id('XXX')
result = html.tostring(element).decode('utf-8')

print(result)

>>> <div id="XXX">XXX content</div>
>>> Text node 2

Он выбирает <div> и следующий Text node 1 по некоторым странным причинам


Если я обертываю <div id="XXX">XXX content</div> с другим <div> в:

Text node 1
<div>
    <div id="XXX">XXX content</div>
</div>
Text node 2

Все лучше, печатает совпавшие <div id="XXX"> и пустые строки (декодированные \n):

>>> print(result)
<div id="XXX">XXX content</div>
\n

Если я добавлю <div> после <div id="XXX"> к:

Text node 1
<div id="XXX">XXX content</div>
<div></div>
Text node 2

Все также лучше, печатает совпавшие <div id="XXX"> и пустую строку(расшифрованный \n):

>>> print(result)
<div id="XXX">XXX content</div>
\n

Предыдущий Text node 1 никогда не влиял - по крайней мере, это нормально)

Итак, что-то можно указатьне выбирать следующие текстовые узлы?Было бы замечательно, если \n также не будет совпадать, но я мог бы жить с этим

Скажите, пожалуйста, если эта проблема связана не с lxml, а с XPath в целом

PS BeautifulSoup не имеет таких проблем, даже используя тот же модуль lxml в качестве парсера, он даже не соответствует следующему \n

VERSIONS:

>>> python
Python 3.7.3

>>> pip show lxml
Version: 4.3.4

1 Ответ

1 голос
/ 19 июня 2019

Похоже, иногда нужно просто использовать грубую силу:

tree = html.fromstring(template)
element = tree.get_element_by_id('XXX')

element.tail = None #brute force in action....

result = html.tostring(element).decode('utf-8')
print(result)

Вывод желаемого

<div id="XXX">XXX content</div>

Теперь люди умнее меня должны объяснить, почему мы должны прибегать к этому ...

...