BeautifulSoup 将 > 改为 >

4
我需要使用BeautifulSoup编辑一些现有的HTML文件,但当DOCTYPE包含ATTLIST元素时会出现问题。
以下是一个最简示例。
from bs4 import BeautifulSoup

doc = """
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
[<!ATTLIST span bodyref CDATA #IMPLIED>]>
<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta content="application/xhtml+xml; charset=utf-8" http-equiv="Content-type"/>
    <meta content="CA43667" name="dc:identifier"/>
  </head>
</html>
"""

soup = BeautifulSoup(doc, features='html.parser')
print(soup.prettify())

输出结果为:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
[<!ATTLIST span bodyref CDATA #IMPLIED>
]&gt;
<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
 <head>
  <meta content="application/xhtml+xml; charset=utf-8" http-equiv="Content-type"/>
  <meta content="CA43667" name="dc:identifier"/>
 </head>
</html>

如您所见,DOCTYPE 的最后一个 '>' 被转换成了一个实体。 使用

print(soup.prettify(formatter=None))

我能理解

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
[<!ATTLIST span bodyref CDATA #IMPLIED>
]>
<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
 <head>
  <meta content="application/xhtml+xml; charset=utf-8" http-equiv="Content-type">
  <meta content="CA43667" name="dc:identifier">
 </head>
</html>

现在DOCTYPE已经正确了,但是“meta”元素中的结束斜线会消失,因此文档将无法在我们的系统上验证。其他格式化选项也似乎无法解决这个问题。
有什么解决办法吗?

关于我的已删除的回答:令我失望的是,lxml XML解析器也不能处理ATTLIST。 - Konrad Rudolph
1个回答

0
你是否正在运行最新版本的BeautifulSoup?我认为你只需要更新BeautifulSoup。或者这可能是一个奇怪的BeautifulSoup安装问题。请在命令行中尝试以下操作:
pip uninstall beautifulsoup4
pip install beautifulsoup4

当我运行这个时:

from bs4 import BeautifulSoup

doc = """
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
[<!ATTLIST span bodyref CDATA #IMPLIED>]>
<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta content="application/xhtml+xml; charset=utf-8" http-equiv="Content-type"/>
    <meta content="CA43667" name="dc:identifier"/>
  </head>
</html>
"""

soup = BeautifulSoup(doc, features='html.parser')
print(soup.prettify(formatter=None))

这是输出:

<?xml version='1.0' encoding='UTF-8'?>                                                                                                                                             
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"                                                                                                                     
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"                                                                                                                          
[<!ATTLIST span bodyref CDATA #IMPLIED>                                                                                                                                            
]>                                                                                                                                                                                 
<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">                                                                                                                          
 <head>                                                                                                                                                                            
  <meta content="application/xhtml+xml; charset=utf-8" http-equiv="Content-type"/>                                                                                                 
  <meta content="CA43667" name="dc:identifier"/>                                                                                                                                   
 </head>                                                                                                                                                                           
</html>      

我相信这就是你要找的内容。我也在一个在线IDE上测试过,似乎与我的电脑匹配。这是一个链接: https://onlinegdb.com/HyzXahzAE


谢谢。我升级了BeautifulSoup和最新的Python版本,但仍然得到了我上面描述的结果。真奇怪。如果有影响的话,我使用的是OSX系统。 - Patrik
@Patrik OSX 不应该有任何影响。我会留下我的答案以帮助其他人。我能想到的唯一的建议就是对其进行黑客攻击,并进行字符串替换,用 &gt;代替。 - Tom Dee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接