使用lxml的html.tostring保留HTML布尔属性值的方法咨询
保留lxml序列化HTML时布尔属性的原始值
确实,lxml的HTML序列化器默认遵循HTML规范,会将值与属性名相同的布尔属性简化为无值形式(比如noresize代替noresize="noresize"),哪怕解析后attrib字典里还保留着原始值。要保留原始的属性值,有两种可行的方法:
方法1:使用XML模式序列化
如果你能接受XML风格的输出(比如自闭合标签),可以在调用html.tostring时指定method='xml'参数,这会强制保留所有属性的键值对:
from lxml import html html_frag = "<iframe src=\"https://src.com/link\" width=\"300\" height=\"300\" scrolling=\"no\" noresize=\"noresize\"></iframe>" html_tree = html.fragments_fromstring(html_frag, parser=html.HTMLParser()) html_str = "" for element in html_tree: print(element.attrib) # 添加method='xml'参数强制保留属性值 html_str += html.tostring(element, encoding=str, method='xml') print(html_str)
运行结果:
{'src': 'https://src.com/link', 'width': '300', 'height': '300', 'scrolling': 'no', 'noresize': 'noresize'} <iframe src="https://src.com/link" width="300" height="300" scrolling="no" noresize="noresize"/>
注意:这种方式会把原来的<iframe></iframe>变成自闭合的<iframe/>,如果需要保持原来的双标签结构,可以用第二种方法。
方法2:自定义序列化逻辑
如果要严格保持原始的HTML标签结构,同时保留属性值,可以手动构建HTML字符串,完全控制每个标签和属性的输出形式:
from lxml import html def serialize_element(element): # 遍历属性,逐个拼接成key="value"的格式 attrs = ' '.join([f'{key}="{value}"' for key, value in element.attrib.items()]) # 处理无内容的标签,保持双标签闭合形式 if len(element) == 0 and not element.text: return f'<{element.tag} {attrs}></{element.tag}>' # 处理有子元素/文本内容的标签(示例中iframe无内容,此分支可按需扩展) start_tag = f'<{element.tag} {attrs}>' end_tag = f'</{element.tag}>' content = element.text or '' for child in element: content += serialize_element(child) content += child.tail or '' return start_tag + content + end_tag html_frag = "<iframe src=\"https://src.com/link\" width=\"300\" height=\"300\" scrolling=\"no\" noresize=\"noresize\"></iframe>" html_tree = html.fragments_fromstring(html_frag, parser=html.HTMLParser()) html_str = "" for element in html_tree: print(element.attrib) html_str += serialize_element(element) print(html_str)
运行结果完全符合你的预期:
{'src': 'https://src.com/link', 'width': '300', 'height': '300', 'scrolling': 'no', 'noresize': 'noresize'} <iframe src="https://src.com/link" width="300" height="300" scrolling="no" noresize="noresize"></iframe>
这个方法适合需要精准匹配原始HTML结构的场景,完全自定义了序列化流程。
内容的提问来源于stack exchange,提问作者user3501283
相关产品推荐
相关产品推荐

