【问题标题】:How to remove HTML tags in BeautifulSoup when I have contents当我有内容时如何在 BeautifulSoup 中删除 HTML 标签
【发布时间】:2016-10-14 21:16:21
【问题描述】:

我试图抓取的 html:

<div id="unitType"> <h2>BB100 <br>v1.4.3</h2> </div>

我在下面有一个h2 标记的内容:

initialPage = beautifulSoup(urllib.urlopen(url).read(), 'html.parser')
deviceInfo = initialPage.find('div', {'id': 'unitType'}).h2.contents
print('Device Info: ', deviceInfo)
for i in deviceInfo:
    print i

哪些输出:

('Device Info: ', [u'BB100 ', <br>v1.4.3</br>])
BB100
<br>v1.4.3</br>

如何使用 BeautifulSoup 而不是正则表达式删除 &lt;h2&gt;&lt;/h2&gt;&lt;br&gt;&lt;/br&gt; html 标签?我试过i.decompose()i.strip(),但都没有奏效。它会抛出'NoneType' object is not callable

【问题讨论】:

  • 我很确定&lt;br&gt; 里面没有任何东西。在 HTML5 中,&lt;/br&gt; 无效。
  • 好点。可能只需要求助于字符串替换。不知道是谁写了这段代码,但他们一定早就不在了。
  • @Richard,为什么你只需要 br 就遍历内容?
  • @PadraicCunningham 我仍然想要这两个值。我只是在寻找一种 Beautiful Soup 方法来摆脱
    和 同时保留“v.1.4.3”。我不需要遍历内容来修改它们?这是我第一次尝试 Beautiful Soup。
  • @Richard,不,您可以使用 .find、.select、.find_all 等。您不需要查看所有内容,您可以按照我的回答进行替换用你喜欢的任何东西替换和节点

标签: python python-2.7 beautifulsoup


【解决方案1】:

只需使用 find 和 extract br 标签:

In [15]: from bs4 import BeautifulSoup
    ...: 
    ...: h = """<div id='unitType'><h2>BB10<br>v1.4.3</h2></d
    ...: iv>"""
    ...: 
    ...: soup = BeautifulSoup(h, "html.parser")
    ...: 
    ...: h2 = soup.find(id="unitType").h2
    ...: h2.find("br").extract()
    ...: print(h2)
    ...: 
<h2>BB10</h2>

或者用 replace-with 的文本替换标签:

In [16]: from bs4 import BeautifulSoup
    ...: 
    ...: h = """<div id='unitType'><h2<br>v1.4.3 BB10</h2></d
    ...: iv>"""
    ...: 
    ...: soup = BeautifulSoup(h, "html.parser")
    ...: 
    ...: h2 = soup.find(id="unitType").h2
    ...: 
    ...: br = h2.find("br")
    ...: br.replace_with(br.text)
    ...: print(h2)
    ...: 
<h2>v1.4.3 BB10</h2>

删除 h2 并保留文本:

In [37]: h = """<div id='unitType'><h2><br>v1.4.3</h2></d
    ...: 
    ...: iv>"""
    ...: 
    ...: soup = BeautifulSoup(h, "html.parser")
    ...: 
    ...: unit = soup.find(id="unitType")
    ...: 
    ...: h2 = unit.find("h2")
    ...: h2.replace_with(h2.text)
    ...: print(unit)
    ...: 
<div id="unitType">v1.4.3 BB10</div>

如果你只想要"v1.4.3""BB10",有很多方法可以让他们嗨起来:

In [60]: h = """<div id="unitType">
    ...:      <h2>BB100 <br>v1.4.3</h2>
    ...:  </div>"""
    ...: 
    ...: soup = BeautifulSoup(h, "html.parser")
    ...: 
    ...: h2 = soup.find(id="unitType").h2
        # just find all strings
    ...: a,b = h2.find_all(text=True)
    ...: print(a, b)
         # get the br
    ...: br = h2.find("br")
        # get br text and just the h2 text ignoring any text from children
    ...: a, b = h2.find(text=True, recursive=False),  br.text
    ...: print(a, b)
    ...: 
BB100  v1.4.3
BB100  v1.4.3

为什么你会得到文本插入

【讨论】:

  • 我希望删除
    和 ,同时保留“v1.4.3”。在您的第一个示例中,打印 h2 会返回 ('Device Info: ', &lt;h2&gt;BB100 &lt;/h2&gt;)
  • 那么你只需要使用第二个例子。
  • 去除h2标签后你的方法是什么?我需要“BB100”和“v1.4.3”作为单独的字符串值。
  • 所以你只想要文本?
  • 是的,先生。所以我可以将字符串文本值与其他字符串进行比较。根据 csv 列表验证型号和固件版本。
【解决方案2】:

您可以使用if i.name == 'br' 检查元素是否为&lt;br&gt; 标签,然后只需将列表更改为包含内容即可。

for i in deviceInfo:
    if i.name == 'br':
        i = i.contents

如果需要多次迭代,修改列表。

for n, i in enumerate(deviceInfo):
    if i.name == 'br':
        i = i.contents
        deviceInfo[n] = i

【讨论】:

  • 感谢您的回复。根据您所拥有的构建,我添加了print i[0],它将返回“v1.4.3”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-26
  • 2014-03-12
  • 1970-01-01
  • 1970-01-01
  • 2020-03-08
  • 1970-01-01
相关资源
最近更新 更多