python类HTMLParser错误解析问题

1 投票
2 回答
1461 浏览
提问于 2025-04-17 08:58

考虑一下下面的html输入:

<html>
<head>
<script>
function open_tools(tool_div)
{
  document.getElementById("tool1").innerHTML = "<a href='javascript:void(0);' onclick=\"javascript:clos_tools('""');\"><img src='menu.gif' border='0' /></a>";
  document.getElementById("tool").innerHTML  = "<a href='javascript:void(0);' onclick=\"javascript:open_tools('""');\"><img src='plus.gif' border='0' /></a>";
}
</script>
</head>
<body /> 
</html>

为了快速测试,假设你把这些html数据放在'test.html'里。在python命令行中,

>>> f = open('test.html', 'r')
>>> data = f.read()
>>> from HTMLParser import HTMLParser
>>> p = HTMLParser()
>>> p.feed(data)

结果是...出现了以下错误

  File "lib\HTMLParser.py", line 155, in goahead
    k = self.parse_starttag(i)   File "lib\HTMLParser.py", line 235, in parse_starttag
    endpos = self.check_for_whole_start_tag(i)   File "lib\HTMLParser.py", line 319, in check_for_whole_start_tag
    self.error("malformed start tag")   File "lib\HTMLParser.py", line 115, in error
    raise HTMLParseError(message, self.getpos()) HTMLParseError: malformed start tag, at line 7, column 88

我对这个错误困惑了整整6个小时。这是我在HTMLParser.py代码中发现的:

在解析的时候,当遇到

2 个回答

2

HTMLParser模块的标题在文档中已经说得很清楚:

HTMLParser — 简单的HTML和XHTML解析器

这里的“简单”确实就是指简单

如果你想进行更复杂的HTML解析,建议使用BeautifulSoup或者lxml

编辑

关于错误的具体问题:

这个错误似乎和问题13358中报告的一个bug有关,修复这个bug的更新应该会包含在下一个版本的Python 2.7和3.2中。

(不过我还是坚持我之前的说法;-)

4

看起来它在第一个语句的 </a> 标签中找到了脚本标签的结束。

没错,这样做是符合HTML4标准的。

在HTML5(以及它继承的SGML)中,像 <script><style> 这样的CDATA元素是通过 </(结束标签的标记)来结束的。如果这个标记不是成对出现的结束标签的一部分,那就是错误的。

所以,要符合HTML4标准,就必须确保脚本块中没有 </ 这样的标记。如果你是在写自己的代码,最简单的方法是把它们写成JS字符串字面量的转义形式,比如 <\/\x3C/。不过如果是自己的代码,建议使用DOM方法,这样可以避免很多转义的问题。

在HTML5中,这个规则有所改变,只有匹配的结束标签才能结束一个CDATA块。这更接近传统浏览器的行为。如果你使用像 html5lib 这样的HTML5解析器,就没问题了。

撰写回答