如何使用选择器保留所有 html 元素但删除所有其他元素?
How to keep all html elements with selector but drop all others?
我想得到一个没有某些元素的 HTML 字符串。但是,预先我只知道要保留哪些元素,但不知道要删除哪些元素。
假设我只想将所有 p
和 a
标签保留在 div
和 class="A"
内。
输入:
<div class="A">
<p>Text1</p>
<img src="A.jpg">
<div class="sub1">
<p>Subtext1</p>
</div>
<p>Text2</p>
<a href="url">link text</a>
</div>
<div class="B">
ContentDiv2
</div>
预期输出:
<div class="A">
<p>Text1</p>
<p>Text2</p>
<a href="url">link text</a>
</div>
如果我知道所有其他元素的所有选择器,我可以使用 lxml
的 drop_tree()
。但问题是我事先不知道['img', 'div.sub1', 'div.B']
。
示例drop_tree()
:
import lxml.cssselect
import lxml.html
tree = lxml.html.fromstring(html_str)
elements_drop = ['img', 'div.sub1', 'div.B']
for j in elements_drop:
selector = lxml.cssselect.CSSSelector(j)
for e in selector(tree):
e.drop_tree()
output = lxml.html.tostring(tree)
我仍然不完全确定我理解正确,但看起来您可能正在寻找与此类似的内容:
target = tree.xpath('//div[@class="A"]')[0]
to_keep = target.xpath('//p | //a')
for t in target.xpath('.//*'):
if t not in to_keep:
target.remove(t) #I believe this method is better here than drop_tree()
print(lxml.html.tostring(target).decode())
我得到的输出是您的预期输出。
试试下面的方法。想法是清理根并添加所需的子元素。
请注意不需要外部库。
import xml.etree.ElementTree as ET
html = '''<div class="A">
<p>Text1</p>
<img src="A.jpg"/>
<div class="sub1">
<p>Subtext1</p>
</div>
<p>Text2</p>
<a href="url">link text</a>
ContentDiv2
</div>'''
root = ET.fromstring(html)
p_lst = root.findall('./p')
a_lst = root.findall('./a')
children = list(root)
for c in children:
root.remove(c)
for p in p_lst:
p.tail = ''
root.append(p)
for a in a_lst:
a.tail = ''
root.append(a)
root.text = ''
ET.dump(root)
输出
<?xml version="1.0" encoding="UTF-8"?>
<div class="A">
<p>Text1</p>
<p>Text2</p>
<a href="url">link text</a>
</div>
我想得到一个没有某些元素的 HTML 字符串。但是,预先我只知道要保留哪些元素,但不知道要删除哪些元素。
假设我只想将所有 p
和 a
标签保留在 div
和 class="A"
内。
输入:
<div class="A">
<p>Text1</p>
<img src="A.jpg">
<div class="sub1">
<p>Subtext1</p>
</div>
<p>Text2</p>
<a href="url">link text</a>
</div>
<div class="B">
ContentDiv2
</div>
预期输出:
<div class="A">
<p>Text1</p>
<p>Text2</p>
<a href="url">link text</a>
</div>
如果我知道所有其他元素的所有选择器,我可以使用 lxml
的 drop_tree()
。但问题是我事先不知道['img', 'div.sub1', 'div.B']
。
示例drop_tree()
:
import lxml.cssselect
import lxml.html
tree = lxml.html.fromstring(html_str)
elements_drop = ['img', 'div.sub1', 'div.B']
for j in elements_drop:
selector = lxml.cssselect.CSSSelector(j)
for e in selector(tree):
e.drop_tree()
output = lxml.html.tostring(tree)
我仍然不完全确定我理解正确,但看起来您可能正在寻找与此类似的内容:
target = tree.xpath('//div[@class="A"]')[0]
to_keep = target.xpath('//p | //a')
for t in target.xpath('.//*'):
if t not in to_keep:
target.remove(t) #I believe this method is better here than drop_tree()
print(lxml.html.tostring(target).decode())
我得到的输出是您的预期输出。
试试下面的方法。想法是清理根并添加所需的子元素。
请注意不需要外部库。
import xml.etree.ElementTree as ET
html = '''<div class="A">
<p>Text1</p>
<img src="A.jpg"/>
<div class="sub1">
<p>Subtext1</p>
</div>
<p>Text2</p>
<a href="url">link text</a>
ContentDiv2
</div>'''
root = ET.fromstring(html)
p_lst = root.findall('./p')
a_lst = root.findall('./a')
children = list(root)
for c in children:
root.remove(c)
for p in p_lst:
p.tail = ''
root.append(p)
for a in a_lst:
a.tail = ''
root.append(a)
root.text = ''
ET.dump(root)
输出
<?xml version="1.0" encoding="UTF-8"?>
<div class="A">
<p>Text1</p>
<p>Text2</p>
<a href="url">link text</a>
</div>