Python, lxml и удаление внешнего тега с помощью lxml.html.tostring (el) - PullRequest
5 голосов
/ 14 февраля 2012

Я использую ниже, чтобы получить все HTML-содержание раздела для сохранения в базе данных

el = doc.get_element_by_id('productDescription')
lxml.html.tostring(el)

Описание продукта имеет тег, который выглядит следующим образом:

<div id='productDescription'>

     <THE HTML CODE I WANT>

</div>

Код работает отлично, дает мне весь HTML-код, но как мне удалить внешний слой, то есть <div id='productDescription'> и закрывающий тег </div>?

Ответы [ 4 ]

3 голосов
/ 15 февраля 2012

, если ваш productDescription div div содержит смешанный текст / элементы содержимого, например,

<div id='productDescription'>
  the
  <b> html code </b>
  i want
</div>

вы можете получить содержимое (в строке), используя xpath('node()') traversal:

s = ''
for node in el.xpath('node()'):
    if isinstance(node, basestring):
        s += node
    else:
        s += lxml.html.tostring(node, with_tail=False)
3 голосов
/ 14 февраля 2012

Вы можете преобразовать каждого потомка в строку отдельно:

text = el.text
text += ''.join(map(lxml.html.tostring, el.iterchildren()))

Или еще более хакерским способом:

el.attrib.clear()
el.tag = '|||'
text = lxml.html.tostring(el)
assert text.startswith('<'+el.tag+'>') and text.endswith('</'+el.tag+'>')
text = text[len('<'+el.tag+'>'):-len('</'+el.tag+'>')]
0 голосов
/ 02 апреля 2017

Использовать регулярное выражение.

def strip_outer_tag(html_fragment):
    import re
    outer_tag = re.compile(r'^<[^>]+>(.*?)</[^>]+>$', re.DOTALL)
    return outer_tag.search(html_fragment).group(1)

html_fragment = strip_outer_tag(tostring(el, encoding='unicode'))  # `encoding` is optionaly
0 голосов
/ 20 апреля 2013

Вот функция, которая делает то, что вы хотите.

def strip_outer(xml):
    """
    >>> xml = '''<math xmlns="http://www.w3.org/1998/Math/MathML" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/1998/Math/MathML         http://www.w3.org/Math/XMLSchema/mathml2/mathml2.xsd">
    ...   <mrow>
    ...     <msup>
    ...       <mi>x</mi>
    ...       <mn>2</mn>
    ...     </msup>
    ...     <mo> + </mo>
    ...     <mi>x</mi>
    ...   </mrow>
    ... </math>'''
    >>> so = strip_outer(xml)
    >>> so.splitlines()[0]=='<mrow>'
    True

    """
    xml = xml.replace('xmlns=','xmlns:x=')#lxml fails with xmlns= attribute
    xml = '<root>\n'+xml+'\n</root>'#...and it can't strip the root element
    rx = lxml.etree.XML(xml)
    lxml.etree.strip_tags(rx,'math')#strip <math with all attributes
    uc=lxml.etree.tounicode(rx)
    uc=u'\n'.join(uc.splitlines()[1:-1])#remove temporary <root> again
    return uc.strip()
...