Tôi có đôi chút mã này:Làm thế nào để prettify HTML để các thuộc tính thẻ sẽ vẫn còn trong một dòng duy nhất?
text = """<html><head></head><body>
<h1 style="
text-align: center;
">Main site</h1>
<div>
<p style="
color: blue;
text-align: center;
">text1
</p>
<p style="
color: blueviolet;
text-align: center;
">text2
</p>
</div>
<div>
<p style="text-align:center">
<img src="./foo/test.jpg" alt="Testing static images" style="
">
</p>
</div>
</body></html>
"""
import sys
import re
import bs4
def prettify(soup, indent_width=4):
r = re.compile(r'^(\s*)', re.MULTILINE)
return r.sub(r'\1' * indent_width, soup.prettify())
soup = bs4.BeautifulSoup(text, "html.parser")
print(prettify(soup))
Kết quả của đoạn mã trên ngay bây giờ là:
<html>
<head>
</head>
<body>
<h1 style="
text-align: center;
">
Main site
</h1>
<div>
<p style="
color: blue;
text-align: center;
">
text1
</p>
<p style="
color: blueviolet;
text-align: center;
">
text2
</p>
</div>
<div>
<p style="text-align:center">
<img alt="Testing static images" src="./foo/test.jpg" style="
"/>
</p>
</div>
</body>
</html>
Tôi muốn tìm ra cách để định dạng đầu ra để nó trở thành này thay vào đó:
<html>
<head>
</head>
<body>
<h1 style="text-align: center;">
Main site
</h1>
<div>
<p style="color: blue;text-align: center;">
text1
</p>
<p style="color: blueviolet;text-align: center;">
text2
</p>
</div>
<div>
<p style="text-align:center">
<img alt="Testing static images" src="./foo/test.jpg" style=""/>
</p>
</div>
</body>
</html>
Nói cách khác, tôi muốn giữ các câu lệnh html như <tag attrib1=value1 attrib2=value2 ... attribn=valuen>
trong một dòng nếu có thể. Khi tôi nói "nếu có thể", tôi có nghĩa là không tự sửa giá trị của các thuộc tính (value1, value2, ..., valuen).
Điều này có thể đạt được với beautifulsoup4 không? Theo tôi đã đọc trong các tài liệu có vẻ như bạn có thể sử dụng một tuỳ chỉnh formatter nhưng tôi không biết làm thế nào tôi có thể có một định dạng tùy chỉnh để nó có thể thực hiện các yêu cầu được mô tả.
EDIT:
@alecxe giải pháp khá đơn giản, không may thất bại trong một số trường hợp phức tạp hơn như hình dưới đây, ví dụ:
test1 = """
<div id="dialer-capmaign-console" class="fill-vertically" style="flex: 1 1 auto;">
<div id="sessionsGrid" data-columns="[
{ field: 'dialerSession.startTime', format:'{0:G}', title:'Start time', width:122 },
{ field: 'dialerSession.endTime', format:'{0:G}', title:'End time', width:122, attributes: {class:'tooltip-column'}},
{ field: 'conversationStartTime', template: cty.ui.gct.duration_dialerSession_conversationStartTime_endTime, title:'Duration', width:80},
{ field: 'dialerSession.caller.lastName',template: cty.ui.gct.person_dialerSession_caller_link, title:'Caller', width:160 },
{ field: 'noteType',template:cty.ui.gct.nameDescription_noteType, title:'Note type', width:150, attributes: {class:'tooltip-column'}},
{ field: 'note', title:'Note'}
]">
</div>
</div>
"""
from bs4 import BeautifulSoup
import re
def prettify(soup, indent_width=4, single_lines=True):
if single_lines:
for tag in soup():
for attr in tag.attrs:
print(tag.attrs[attr], tag.attrs[attr].__class__)
tag.attrs[attr] = " ".join(
tag.attrs[attr].replace("\n", " ").split())
r = re.compile(r'^(\s*)', re.MULTILINE)
return r.sub(r'\1' * indent_width, soup.prettify())
def html_beautify(text):
soup = BeautifulSoup(text, "html.parser")
return prettify(soup)
print(html_beautify(test1))
traceback:
dialer-capmaign-console <class 'str'>
['fill-vertically'] <class 'list'>
Traceback (most recent call last):
File "d:\mcve\x.py", line 35, in <module>
print(html_beautify(test1))
File "d:\mcve\x.py", line 33, in html_beautify
return prettify(soup)
File "d:\mcve\x.py", line 25, in prettify
tag.attrs[attr].replace("\n", " ").split())
AttributeError: 'list' object has no attribute 'replace'
Chấp nhận và tặng tiền thưởng ở đây vì những lý do tiếp theo: 1) Câu hỏi đề cập đến bs4 và câu hỏi này liên quan đến các yêu cầu 2) Số lượng upvotes từ mọi người và câu trả lời đầu tiên cho đất 3) @carlo chen answer không hoạt động , ví dụ: tidylib không phải là một gói tự chứa và nó đòi hỏi một số dlls bên ngoài. – BPL