8.7. 为属性值加引号

comp.lang.python 上的一个常见问题是“我有一堆没有为属性值加引号的 HTML 文档,我想为它们全部正确地加上引号。我该怎么做?[4] (这通常是由项目经理发现 HTML-是一种标准的宗教加入了一个大型项目,并宣称所有页面都必须通过 HTML 验证器验证而引发的。未加引号的属性值是违反 HTML 标准的常见行为。)无论出于何种原因,未加引号的属性值都可以通过将 HTML 输入 BaseHTMLProcessor 来轻松修复。

BaseHTMLProcessor 会解析 HTML(因为它继承自 SGMLParser)并生成等效的 HTML,但输出的 HTML 与输入并不完全相同。标签和属性名称最终将变为小写,即使它们最初是大写或混合大小写,并且属性值将用双引号括起来,即使它们最初是用单引号或根本没有引号括起来。您可以利用这最后一个副作用。

示例 8.16. 为属性值加引号

>>> htmlSource = """        1
...     <html>
...     <head>
...     <title>Test page</title>
...     </head>
...     <body>
...     <ul>
...     <li><a href=index.html>Home</a></li>
...     <li><a href=toc.html>Table of contents</a></li>
...     <li><a href=history.html>Revision history</a></li>
...     </body>
...     </html>
...     """
>>> from BaseHTMLProcessor import BaseHTMLProcessor
>>> parser = BaseHTMLProcessor()
>>> parser.feed(htmlSource) 2
>>> print parser.output()   3
<html>
<head>
<title>Test page</title>
</head>
<body>
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="toc.html">Table of contents</a></li>
<li><a href="history.html">Revision history</a></li>
</body>
</html>
1 请注意,<a> 标签中 href 属性的属性值没有正确加引号。(另请注意,您正在将 三引号 用于 文档字符串 以外的内容。而且直接在 IDE 中使用。它们非常有用。)
2 将代码输入解析器。
3 使用 BaseHTMLProcessor 中定义的 output 函数,您可以获得作为单个字符串的输出,并带有加引号的属性值。虽然这看起来可能有点虎头蛇尾,但想想这里实际发生了什么:SGMLParser 解析了整个 HTML 文档,将其分解为标签、引用、数据等等;BaseHTMLProcessor 使用这些元素来重建 HTML 片段(如果您想查看它们,它们仍然存储在 parser.pieces 中);最后,您调用了 parser.output,它将所有 HTML 片段连接成一个字符串。

脚注

[4] 好吧,这并不是一个那么常见的问题。它不像“我应该使用什么编辑器来编写 Python 代码?”(答案:Emacs)或“PythonPerl 好还是差?”(答案:“PerlPython 差,因为人们希望它更差。 ”-Larry Wall,1998 年 10 月 14 日)那么常见。但关于 HTML 处理的问题大约每个月都会以一种或另一种形式出现,而在这些问题中,这是一个很受欢迎的问题。