有没有办法定义.prettify()函数的自定义缩进宽度?从我能从它的来源得到的东西-
def prettify(self, encoding=None, formatter="minimal"):
if encoding is None:
return self.decode(True, formatter=formatter)
else:
return self.encode(encoding, True, formatter=formatter)无法指定缩进宽度。我认为这是因为decode_contents()函数中的这一行-
s.append(" " * (indent_level - 1))它的固定长度为1个空格!(为什么!)我尝试指定indent_level=4,结果却是这样-
<section>
<article>
<h1>
</h1>
<p>
</p>
</article>
</section>这看起来太愚蠢了。:
现在,我可以解决这个问题,但我只想确定我是否遗漏了什么。因为这应该是一个基本特性。:-/
如果你有更好的方法来美化HTML代码,请告诉我。
发布于 2013-03-20 09:06:35
实际上,我自己处理了这个问题,以一种最简单的方式:对结果进行后处理。
r = re.compile(r'^(\s*)', re.MULTILINE)
def prettify_2space(s, encoding=None, formatter="minimal"):
return r.sub(r'\1\1', s.prettify(encoding, formatter))实际上,我在类中用prettify_2space代替了prettify。这对解决方案来说不是必须的,但无论如何让我们这样做,并将缩进宽度作为参数,而不是将其硬编码为2:
orig_prettify = bs4.BeautifulSoup.prettify
r = re.compile(r'^(\s*)', re.MULTILINE)
def prettify(self, encoding=None, formatter="minimal", indent_width=4):
return r.sub(r'\1' * indent_width, orig_prettify(self, encoding, formatter))
bs4.BeautifulSoup.prettify = prettify所以:
x = '''<section><article><h1></h1><p></p></article></section>'''
soup = bs4.BeautifulSoup(x)
print(soup.prettify(indent_width=3))…提供:
<html>
<body>
<section>
<article>
<h1>
</h1>
<p>
</p>
</article>
</section>
</body>
</html>显然,如果你想像修补BeautifulSoup.prettify一样修补Tag.prettify,你必须在那里做同样的事情。(您可能希望创建一个可以同时应用于两者的通用包装器,而不是重复使用。)如果有任何其他的prettify方法,同样的处理。
发布于 2013-03-20 08:59:57
据我所知,这个功能不是内置的,因为这个问题有几个解决方案。
假设您使用的是BeautifulSoup 4,下面是我提出的解决方案
硬编码。这需要最小的改变,如果你不需要在不同的环境中缩进不同,这是很好的:
myTab = 4 # add this
if pretty_print:
# space = (' ' * (indent_level - 1))
space = (' ' * (indent_level - myTab))
#indent_contents = indent_level + 1
indent_contents = indent_level + myTab 前一种解决方案的另一个问题是,文本内容不会完全一致地缩进,但仍然很吸引人。如果您需要更灵活/一致的解决方案,只需修改类即可。
找到prettify函数并进行相应的修改(它位于element.py的Tag类中):
#Add the myTab keyword to the functions parameters (or whatever you want to call it), set it to your preferred default.
def prettify(self, encoding=None, formatter="minimal", myTab=2):
Tag.myTab= myTab # add a reference to it in the Tag class
if encoding is None:
return self.decode(True, formatter=formatter)
else:
return self.encode(encoding, True, formatter=formatter)然后向上滚动到Tag类中的decode方法,并进行以下更改:
if pretty_print:
#space = (' ' * (indent_level - 1))
space = (' ' * (indent_level - Tag.myTab))
#indent_contents = indent_level + Tag.myTab
indent_contents = indent_level + Tag.myTab然后转到标记类中的decode_contents方法并进行以下更改:
#s.append(" " * (indent_level - 1))
s.append(" " * (indent_level - Tag.myTab))现在BeautifulSoup('Text').prettify(myTab=4)将返回:
<root>
<child>
<desc>
Text
</desc>
</child>
</root>** BeautifulSoup类继承了Tag类,无需打补丁。修补标记类就足以实现这一目标。
发布于 2020-07-27 14:08:58
这里有一种方法可以增加缩进,而不需要干预原始函数等。创建以下函数:
# Increase indentation of 'text' by 'n' spaces
def add_indent(text,n):
sp = " "*n
lsep = chr(10) if text.find(chr(13)) == -1 else chr(13)+chr(10)
lines = text.split(lsep)
for i in range(len(lines)):
spacediff = len(lines[i]) - len(lines[i].lstrip())
if spacediff: lines[i] = sp*spacediff + lines[i]
return lsep.join(lines)然后使用上面的函数转换您获得的文本:
x = '''<section><article><h1></h1><p></p></article></section>'''
soup = bs4.BeautifulSoup(x, 'html.parser') # I don't know if you need 'html.parser'
text = soup.prettify() # I do, otherwise I get a warning
text = add_indent(text,1) # Increase indentation by 1 space
print(text)
'''
Output:
<html>
<body>
<section>
<article>
<h1>
</h1>
<p>
</p>
</article>
</section>
</body>
</html>
'''https://stackoverflow.com/questions/15509397
复制相似问题