python:获取开始和结束html标签

标签 python html python-3.x beautifulsoup html-parsing

问题:

如何使用 python (3.6) 找到所有开始和结束 HTML 标记的文本。 这需要是准确的文本,保留空格和可能非法的 html:

# input
html = """<p>This <a href="book"> book </a  > will help you</p attr="e">"""

# desired output
output = ['<p>', '<a href="book">', '</a  >', '</p attr="e">']

尝试解决方案:

显然这在Beautifulsoup中是不可能的,这个问题:How to get the opening and closing tag in beautiful soup from HTML string?链接到 html.parser

实现自定义解析器很容易。您可以使用self.get_starttag_text()获取与最后打开的标签对应的文本。但由于某种原因,没有类似的方法 get_endtag_text()

这意味着我的解析器会产生以下输出:

class MyHTMLParser(HTMLParser):
    def __init__(self):
        super().__init__()
        self.tags = []

    def reset_stored_tags(self):
        self.tags = []
    def handle_starttag(self, tag, attrs):
        self.tags.append(self.get_starttag_text())

    def handle_endtag(self, tag):
        self.tags.append(self.get_endtag_text())

    def handle_startendtag(self, data):
        self.tags.append(self.get_starttag_text())
# input
input_doc = """<p>This <a href="book"> book </a> will help you</p>"""

parser = MyHTMLParser()
parser.feed(input_doc)

print(parser.tags)
# ['<p>', '<a href="book">', '<a href="book">', '<a href="book">']

handle_endtagtag 参数只是一个字符串 "a""p",而不是一些可以提供整个标签的自定义数据类型。

最佳答案

您可以使用递归并迭代 soup.contents 属性:

from bs4 import BeautifulSoup as soup

html = """<p>This <a href="book"> book </a> will help you</p>"""

def attrs(_d):
  if _d.name != '[document]':
    _attrs = ' '.join(f'{a}="{b}"' for a, b in getattr(_d, 'attrs', {}).items())
    yield f'<{_d.name}>' if not _attrs else f'<{_d.name} {_attrs}>'
  for i in _d.contents:
    if not isinstance(i, str):
       yield from attrs(i)
  if _d.name != '[document]':
    yield f'</{_d.name}>'

print(list(attrs(soup(html, 'html.parser'))))

输出:

['<p>', '<a href="book">', '</a>', '</p>']

编辑:对于无效的 HTML,您可以使用 re:

import re
html = """<p>This <a href="book"> book </a  > will help you</p attr="e">"""
new_results = re.findall('\<[a-zA-Z]+.*?\>|\</[a-zA-Z]+.*?\>', html)

输出:

['<p>', '<a href="book">', '</a  >', '</p attr="e">']

关于python:获取开始和结束html标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54352147/

相关文章:

javascript - 在 HTML5 canvas 中不负责任地传播图像

Android webview 未加载包含资源的完整 html 页面

python - 无法在均衡群体财富的程序中找到错误 (UVA 10137, "The Trip")

python - 在 Python 中比较 2 个字符串的最有效方法是什么

python - Django:如何连接分隔的整数字段(年,月)作为日期范围来过滤数据库

python - 求解最小值的不等式

python - 在 Pandas 列中获得第一和第二高的值

python - 如何根据两个列表python计算准确度?

javascript - 使用 HTML 和 Javascript 的表单

python-3.x - Convnet 序数回归损失函数