【问题标题】:How to keep all html elements with selector but drop all others?如何使用选择器保留所有 html 元素但删除所有其他元素?
【发布时间】:2021-11-08 18:02:45
【问题描述】:

我想得到一个没有某些元素的 HTML 字符串。但是,预先我只知道要保留哪些元素,但不知道要删除哪些元素。

假设我只想将所有pa 标签保留在divclass="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>

如果我知道所有其他元素的所有选择器,我可以使用lxmldrop_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)

【问题讨论】:

  • 你的问题不清楚;请编辑您的问题并将另一个&lt;div&gt; 兄弟&lt;div&gt;class="A" 添加到您的html 字符串中,但使用另一个类,然后在给定这个新的html 字符串的情况下准确显示您的预期输出。

标签: python lxml lxml.html


【解决方案1】:

我仍然不能完全确定我的理解是否正确,但您似乎正在寻找类似这样的东西:

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())

我得到的输出是你的预期输出。

【讨论】:

  • 完美的工作!谢谢。我们还可以将 xpath 用于to_keep,这样我们就可以使用更复杂的选择器。
【解决方案2】:

试试下面的。这个想法是清理根并添加所需的子元素。

请注意,不需要外部库

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>

【讨论】:

  • 完美!如果有人不想使用外部库,这是一个很好的解决方案!无论如何我都在使用lxml,所以我对@jack-fleeting 解决方案没有任何问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-11
  • 2012-04-30
  • 1970-01-01
  • 1970-01-01
  • 2012-11-07
相关资源
最近更新 更多