Получить HTML-код под тегом, используя htmlparser python
Я хочу, чтобы получить весь HTML под тегом и с помощью HTMLParser. В настоящее время я могу получить данные между тегами и мой код
class LinksParser(HTMLParser):
def __init__(self):
HTMLParser.__init__(self)
self.recording = 0
self.data = ''
def handle_starttag(self, tag, attributes):
if tag != 'span':
return
if self.recording:
self.recording += 1
return
for name, value in attributes:
if name == 'itemprop' and value == 'description':
break
else:
return
self.recording = 1
def handle_endtag(self, tag):
if tag == 'span' and self.recording:
self.recording -= 1
def handle_data(self, data):
if self.recording:
self.data += data
Я также хочу HTML-теги внутри ввода, например
<span itemprop="description">
<h1>My First Heading</h1>
<p>My first <br/><br/>paragraph.</p>
</span>
когда предоставлено в качестве входных данных, только даст мне данные без тегов. Есть ли способ, с помощью которого я могу получить весь HTML между тегами?
2 ответа
Можно использовать xml.etree.ElementTree.TreeBuilder
использовать etree API для поиска / манипулирования <span>
элемент:
import sys
from HTMLParser import HTMLParser
from xml.etree import cElementTree as etree
class LinksParser(HTMLParser):
def __init__(self):
HTMLParser.__init__(self)
self.tb = etree.TreeBuilder()
def handle_starttag(self, tag, attributes):
self.tb.start(tag, dict(attributes))
def handle_endtag(self, tag):
self.tb.end(tag)
def handle_data(self, data):
self.tb.data(data)
def close(self):
HTMLParser.close(self)
return self.tb.close()
parser = LinksParser()
parser.feed(sys.stdin.read())
root = parser.close()
span = root.find(".//span[@itemprop='description']")
etree.ElementTree(span).write(sys.stdout)
Выход
<span itemprop="description">
<h1>My First Heading</h1>
<p>My first <br /><br />paragraph.</p>
</span>
Для печати без родителя (root) <span>
тег:
sys.stdout.write(span.text)
for child in span:
sys.stdout.write(etree.tostring(child)) # add encoding="unicode" on Python 3
Вот кое-что, что выполняет работу на основе предоставленных вами тестовых данных с минимальными изменениями в существующем коде (при условии, что он в основном делает то, что вы уже хотите). Возможно, вы захотите расширить его, чтобы иметь дело с самозакрывающимися тегами более надежным способом:
from HTMLParser import HTMLParser
class LinksParser(HTMLParser):
def __init__(self):
HTMLParser.__init__(self)
self.recording = 0
self.data = ''
self.self_closing_tags = ("br",)
def handle_starttag(self, tag, attributes):
if tag not in ('span',) + self.self_closing_tags:
self.data += "<%s" % (tag,)
if attributes:
self.data += " " + " ".join('%s="%s"' % (k, v) for k, v in attributes)
self.data += ">"
return
if self.recording:
self.recording += 1
return
for name, value in attributes:
if name == 'itemprop' and value == 'description':
break
else:
return
self.recording = 1
def handle_endtag(self, tag):
if tag == 'span' and self.recording:
self.recording -= 1
elif tag in self.self_closing_tags:
self.data += "<%s/"> % (tag,)
else:
self.data += "</%s>" % (tag,)
def handle_data(self, data):
if self.recording:
self.data += data
Учитывая это как вход:
<span itemprop="description">
<h1>My First Heading</h1>
<p>My first <br/><br/>paragraph.</p>
</span>
выход:
<h1>My First Heading</h1>
<p>My first <br/><br/>paragraph.</p>