python - python:获取打开和关闭html标签
问题描述
问题:
如何使用 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 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">']
的tag
参数handle_endtag
只是一个字符串"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">']
推荐阅读
- excel - 来自数据集的动态 Excel 图表
- android - 防止 EditText 使用特殊字符
- android - GetPackageInfo 导致 DeadObjectException
- php - 如何通过正则表达式收集 HTML-div 中的 url 文本?
- python - html .db 文件的一行中的多个链接引用
- java - 比较 Player 对象属性以检查谁的名字最短
- javascript - @blur 标记清除 Vue.js SPA 组件中的输入值
- freepascal - 将帕斯卡中的变量限制为 1 到 10
- graphql - 如何正确使用'limit'和'start'(获取实例数量)
- javascript - 如何获得产品评论评分值?