Skip to main content
 首页 » 编程设计

python 类 HTMLParser 错误地给出解析错误

2025年05月04日18dudu

考虑以下 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 shell 上,

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

Burrrppp... 出现以下错误

  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 代码中找到的:

解析时,遇到script标签时,设置cdata = true。 之后,它使用 interesting_cdata= re.compile(r'<(/|\Z)')用于找出脚本标记结尾的正则表达式 [在 goahead() 内]

不幸的是,它似乎在 </a> 中找到脚本标记的结尾function open_tools 的第一条陈述而不是在 </script> .然后它在第二行函数中打嗝。

我不知道如何解决这个问题,并且认为 HTMLParser 中的错误令人不安。谁能帮忙?

注意:我是一个 python 业余爱好者,上面用 python 2.6 (windows) 测试过

编辑:是的,它适用于 BeautifulSoup。但我有兴趣知道正则表达式是否损坏(以及如何损坏?及其修复)或者 HTMLParser 类是否存在其他问题。第一步就卡在库代码中是令人沮丧的。 php docs 的好处是能够在官方文档页面上发表评论。 msdn 也同样支持。

请您参考如下方法:

it seems it is finding end of script tag in </a> of first statement

是的,按照HTML4标准这样做是正确的。

在 HTML<5(和从中继承此行为的 SGML)中,像 <script> 这样的 CDATA 元素或 <style>由 </ 结束(ETAGO) 序列。该序列不属于匹配的结束标记是错误的。

因此要验证为 HTML4,必须确保没有 </序列包含在脚本 block 中。 (如果它是你自己的代码,最简单的方法是将它们写成 JS 字符串文字转义,如 <\/ 或 \x3C/ 。但如果它是你自己的代码,你会想看看使用 DOM 方法,以避免所有转义问题。)

在 HTML5 中,这发生了变化,因此只有匹配的结束标记结束 CDATA block 。这更符合传统的浏览器行为。如果您使用 HTML5 解析器,例如 html5lib你会没事的。