Bib*_*ath 27 python code-formatting indentation beautifulsoup
有没有办法为.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)
Run Code Online (Sandbox Code Playgroud)
无法指定缩进宽度.我认为这是因为功能中的这一行decode_contents()-
s.append(" " * (indent_level - 1))
Run Code Online (Sandbox Code Playgroud)
其中固定长度为1个空格!(为什么!!)我尝试指定indent_level=4,这只是导致 -
<section>
<article>
<h1>
</h1>
<p>
</p>
</article>
</section>
Run Code Online (Sandbox Code Playgroud)
这看起来简直是愚蠢的.:|
现在,我可以解决这个问题,但我只是想确定是否有任何我遗漏的东西.因为这应该是一个基本功能.: - /
如果你有更好的方法来美化HTML代码,请告诉我.
aba*_*ert 19
我实际上是以最可能的方式处理这个问题:通过后处理结果.
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))
Run Code Online (Sandbox Code Playgroud)
实际上,我在班上prettify_2space代替了monkeypatched 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
Run Code Online (Sandbox Code Playgroud)
所以:
x = '''<section><article><h1></h1><p></p></article></section>'''
soup = bs4.BeautifulSoup(x)
print(soup.prettify(indent_width=3))
Run Code Online (Sandbox Code Playgroud)
......给出:
<html>
<body>
<section>
<article>
<h1>
</h1>
<p>
</p>
</article>
</section>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
显然,如果要修补Tag.prettify,以及BeautifulSoup.prettify,你必须做同样的事情出现.(您可能希望创建一个可以应用于两者的通用包装器,而不是重复自己.)如果有任何其他prettify方法,同样的交易.
saa*_*aaj 12
Beautiful Soup 有输出格式化程序。bs4.formatter.HTMLFormatter允许指定indent.
>>> import bs4
>>> s = '<section><article><h1></h1><p></p></article></section>'
>>> formatter = bs4.formatter.HTMLFormatter(indent=2)
>>> print(bs4.BeautifulSoup(s, 'html.parser').prettify(formatter=formatter))
<section>
<article>
<h1>
</h1>
<p>
</p>
</article>
</section>
Run Code Online (Sandbox Code Playgroud)
您还可以通过pyfil从命令行使用它(例如与 Geany 的“将选择发送到”功能集成):
pyfil 'bs4.BeautifulSoup(stdin, "html.parser").prettify(formatter=bs4.formatter.HTMLFormatter(indent=2))'
Run Code Online (Sandbox Code Playgroud)
据我所知,此功能不是内置的,因为针对此问题有很多解决方案。
假设您正在使用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
Run Code Online (Sandbox Code Playgroud)
先前解决方案的另一个问题是文本内容不会被完全一致地缩进,但是仍然具有吸引力。如果您需要更灵活/一致的解决方案,则只需修改类。
找到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)
Run Code Online (Sandbox Code Playgroud)
然后向上滚动到Tag类中的解码方法并进行以下更改:
if pretty_print:
#space = (' ' * (indent_level - 1))
space = (' ' * (indent_level - Tag.myTab))
#indent_contents = indent_level + Tag.myTab
indent_contents = indent_level + Tag.myTab
Run Code Online (Sandbox Code Playgroud)
然后转到Tag类中的decode_contents方法并进行以下更改:
#s.append(" " * (indent_level - 1))
s.append(" " * (indent_level - Tag.myTab))
Run Code Online (Sandbox Code Playgroud)
现在BeautifulSoup('<root> <child> <desc> Text </ desc> </ child> </ root>')。prettify(myTab = 4)将返回:
<root>
<child>
<desc>
Text
</desc>
</child>
</root>
Run Code Online (Sandbox Code Playgroud)
**无需修补BeautifulSoup类,因为它继承了Tag类。修补Tag类足以实现目标。
| 归档时间: |
|
| 查看次数: |
7252 次 |
| 最近记录: |