如何使用BeautifulSoup删除pre标签中的空格

-1 投票
1 回答
1437 浏览
提问于 2025-04-17 14:30

考虑一下这段代码。

#!/usr/bin/env python
# -*- coding: utf8 -*-

from bs4 import BeautifulSoup
html_doc = """<pre class="code file d"><span class="kw2">import std.stdio
import core.bitop;

// parallel port address 
const uint port = 0x0c000;

void main()
{
    /*
        permission related stuff under linux
    */

    /* data */
    ubyte data = 0b_11111111;
    outp(port, data);
}
</span></pre>
"""

invalid_tags = ['span']

soup = BeautifulSoup(html_doc)

for tag in invalid_tags:
    for invalid in soup.findAll(tag):
        invalid.replaceWithChildren()

pre_tags = soup.find_all('pre')

for i in range (len(pre_tags)):
    pre_tags[i]['class'] = 'prettyprint'

output = soup.prettify(formatter=None)

output_text = output.encode('utf8', 'replace')

output_file = open('test.html', "w")
output_file.write(output_text)
output_file.close()

我有一个简单的HTML文档。我想去掉一些不需要的标签,比如这里的<span>,并且想要修改<pre>标签的类名。

但是如果你查看输出文件,会发现第二行有多余的空白字符。

  <pre class="prettyprint">
   import std.stdio
import core.bitop;

// parallel port address 
const uint port = 0x0c000;

void main()
{
    /*
        permission related stuff under linux
    */

    /* data */
    ubyte data = 0b_11111111;
    outp(port, data);
}
  </pre>

我想去掉第二列前面多余的空白字符,并且希望它是左对齐的。

我该怎么做呢?有什么想法吗?谢谢。

1 个回答

1

这里的问题在于你调用了 prettify。其他的内容都不重要。如果你在去掉标签的循环之后,打印出 soup,然后在重新分类的循环之后再打印一次,内容是没问题的;但是如果你在一开始就打印 soup.prettify(),而不经过这两个循环,它就已经多加了一些空格。

为什么会这样呢?这就是 prettify 的作用。在文档中,Pretty-printing 说它会把“每个 HTML/XML 标签放在自己的行上”。这也包括 <pre> 标签。

如果你想使用 prettify,但又希望它不处理 pre 标签,你需要创建一个格式化器,并传入这个格式化器来跳过 pre 标签。

或者,你也可以总是做一些类似这样的事情(伪代码,不是真正的代码):

for tag in find_all('pre'):
    replace tag contents with str(len(stash))
    stash.append(str(tag contents))
pretty = soup.prettify()
for i, tag in stash:
    pretty.replace('<pre>{}</pre>'.format(i), tag)

有人认为 prettify 应该总是跳过 pre 标签(就像它对 CData 的处理一样)。可以查看 这个bug

撰写回答