您的位置:首页 > Web前端 > HTML

htmlparser 处理标签的一个bug

2009-07-05 23:53 411 查看
众所周知,Htmlparser本身有一些小bug,而且也有三年没更新了。所以现在基于java的信息抽取多转向NekoHtml。不过Htmlparser本身还是有不少优点,主要是扩展性强,其利用的设计模式值得学习。由于时间的关系,现在项目还是使用Htmlparser,以后有时间会对nekohtml进行研究。
今天遇到的bug来自于对<script>的解析。假如一个网页的部分代码如下,那么HtmlParser是必然会出错的:
<script language="javascript">
var strMsg = "<div aligh=left><span class='font14 style4'><font color=red>******你的投票已提交,谢谢! ******</font></span></div>";
var existStrMsg = "<div aligh=left><span class='font14 style4'><font color=red>******你已经投过票了,谢谢! ******</font></span></div>";
var dealingStrMsg = "<div aligh=left><span class='font14 style4'><font color=red>******正在处理你的投票,请稍后...... ******</font></span></div>";


htmlparser在解析一个节点时,首先确定节点Tag的类型,然后再调用相应的scanner进一步处理。对于<script>标签,需要调用的就是 org.htmlparser.scanners.ScriptScanner。ScriptScanner的Scan()方法部分代码如下:
public static boolean STRICT = true
...
if (tag instanceof ScriptTag)
{
language = ((ScriptTag)tag).getLanguage ();
if ((null != language) &&
(language.equalsIgnoreCase ("JScript.Encode") ||
language.equalsIgnoreCase ("VBScript.Encode")))
{
code = ScriptDecoder.Decode (lexer.getPage (), lexer.getCursor ());
((ScriptTag)tag).setScriptCode (code);
}
}
content = lexer.parseCDATA (!STRICT);
position = lexer.getPosition ();


问题就出在 lexer.parseCDATA() 这个方法上。它提取<scirpt>标签的内容作为文本返回给 content 。当其中的参数为false时,它的截至条件是遇到 “</”。也就是说此时尽管遇到的"</" 是双引号内的文本内容,它仍然会认为遇到了截止标签。对于上文的HTML代码,截止标签就是</font>。出现这个错误后,之后的内容都将被当做普通html代码来解析,直到再遇到</script>。

解决的办法很简单 ,只需将参数改为:
content = lexer.parseCDATA (STRICT);


当参数为true时,该方法会自动考虑引号的问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: