Подтвердить что ты не робот

Эквивалентно InnerHTML при использовании lxml.html для анализа HTML

Я работаю над script с помощью lxml.html для анализа веб-страниц. В свое время я немного поработал над BeautifulSoup, но теперь я экспериментирую с lxml из-за его скорости.

Я хотел бы знать, какой самый разумный способ в библиотеке - сделать эквивалент Javascript InnerHtml - то есть получить или установить полное содержимое тега.

<body>
<h1>A title</h1>
<p>Some text</p>
</body>

InnerHtml:

<h1>A title</h1>
<p>Some text</p>

Я могу сделать это с помощью хаков (преобразование в строку/регулярные выражения и т.д.), но я предполагаю, что есть правильный способ сделать это, используя библиотеку, которую я пропускаю из-за незнания. Спасибо за любую помощь.

EDIT: Благодаря pobk за то, что он показал мне путь к этому так быстро и эффективно. Для тех, кто пытается то же самое, вот что я в итоге:

from lxml import html
from cStringIO import StringIO
t = html.parse(StringIO(
"""<body>
<h1>A title</h1>
<p>Some text</p>
Untagged text
<p>
Unclosed p tag
</body>"""))
root = t.getroot()
body = root.body
print (element.text or '') + ''.join([html.tostring(child) for child in body.iterdescendants()])

Обратите внимание, что синтаксический анализатор lxml.html фиксирует незакрытый тег, поэтому будьте осторожны, если это проблема.

4b9b3361

Ответ 1

Вы можете получить дочерние элементы ElementTree node с помощью методов getchildren() или iterdescendants() корня node:

>>> from lxml import etree
>>> from cStringIO import StringIO
>>> t = etree.parse(StringIO("""<body>
... <h1>A title</h1>
... <p>Some text</p>
... </body>"""))
>>> root = t.getroot()
>>> for child in root.iterdescendants(),:
...  print etree.tostring(child)
...
<h1>A title</h1>

<p>Some text</p>

Это может быть сокращено следующим образом:

print ''.join([etree.tostring(child) for child in root.iterdescendants()])

Ответ 2

Извините за то, что вы снова это сделали, но я искал решение, и у вас есть ошибка:

<body>This text is ignored
<h1>Title</h1><p>Some text</p></body>

Текст непосредственно под корневым элементом игнорируется. Я закончил это:

(body.text or '') +\
''.join([html.tostring(child) for child in body.iterchildren()])

Ответ 3

import lxml.etree as ET

     body = t.xpath("//body");
     for tag in body:
         h = html.fromstring( ET.tostring(tag[0]) ).xpath("//h1");
         p = html.fromstring(  ET.tostring(tag[1]) ).xpath("//p");             
         htext = h[0].text_content();
         ptext = h[0].text_content();

вы также можете использовать .get('href') для тега и .attrib для атрибута,

здесь тег no жестко закодирован, но вы также можете сделать эту динамическую