Java基礎知識:Jtidy解析腳本時候出現問題
最近在做網頁結構化信息抽取,用到了JTidy和xslt.當在處理一些包含很多腳本的頁面時候,出現了,JTidy去臟失敗,提示標題中的異常。
最后發現,問題出現在解析腳本的時候因為一些腳本里面不規范的內容,導致不能判斷結束造成了上面的異常出現。
解決方法:
最初的時候想通過修改JTidy的源碼來解決這個問題,但是后來做著發現可行性不高,一個是修改這個源碼可能會帶來其它的問題。另外一個,還要花長時間去看源碼。
所以,最終還是選擇了采用預處理的方式來進行處理刪除掉腳本。
代碼
[java]
public static String getFilterBody(String strBody) {
// htmlparser 解析
Parser parser = Parser.createParser(strBody, "utf-8");
NodeList list;
String reValue = strBody;
try {
list = parser.parse(null);
visitNodeList(list);
reValue = list.toHtml();
} catch (ParserException e1) {
}
return reValue;
}
// 遞歸過濾
private static void visitNodeList(NodeList list) {
for (int i = 0; i < list.size(); i++) {
Node node = list.elementAt(i);
if (node instanceof Tag) {
if (node instanceof ScriptTag) {
list.remove(i);
continue;
}// 這里可以增加刪除的Tag
if (node instanceof StyleTag) {
list.remove(i);
continue;
}// 這里可以增加刪除的Tag
}
NodeList children = node.getChildren();
if (children != null && children.size() > 0)
visitNodeList(children);
}
}
但是在刪除腳本的時候一樣遇到了相同的問題,就是在解析腳本的時候出現了錯亂,把一些腳本中的標簽識別為正常標簽。如:<script>里面的 '<span></span>'里面的'</'就會被識別為腳本的結束,導致腳本獲取不全,刪除不全最后在網上找到了解決的辦法通過下面兩個參數的設置來解析了html對腳本的處理問題
[java]
org.htmlparser.scanners.ScriptScanner.STRICT = false;
org.htmlparser.lexer.Lexer.STRICT_REMARKS = false;
只要配置其中之一就可以了,下面是這兩個參數的一個官方說明
org.htmlparser.scanners.ScriptScanner.STRICT = false;
[java]
/**
* Strict parsing of CDATA flag.
* If this flag is set true, the parsing of script is performed without
* regard to quotes. This means that erroneous script such as:
* <pre>
* document.write("</script>");
* </pre>
* will be parsed in strict accordance with appendix
* <a href="/TR/html4/appendix/notes.html#notes-specifying-data" mce_href="/TR/html4/appendix/notes.html#notes-specifying-data">
* B.3.2 Specifying non-HTML data</a> of the
* <a href="/TR/html4/" mce_href="/TR/html4/">HTML 4.01 Specification</a> and
* hence will be split into two or more nodes. Correct javascript would
* escape the ETAGO:
* <pre>
* document.write("<//script>");
* </pre>
* If true, CDATA parsing will stop at the first ETAGO ("</") no matter
* whether it is quoted or not. If false, balanced quotes (either single or
* double) will shield an ETAGO. Beacuse of the possibility of quotes within
* single or multiline comments, these are also parsed. In most cases,
* users prefer non-strict handling since there is so much broken script
* out in the wild.
*/
org.htmlparser.lexer.Lexer.STRICT_REMARKS = false;
[java]
/**
* Process remarks strictly flag.
* If <code>true</code>, remarks are not terminated by ---$gt;
* or --!$gt;, i.e. more than two dashes. If <code>false</code>,
* a more lax (and closer to typical browser handling) remark parsing
* is used.
* Default <code>true</code>.
*/
在默認情況下,htmlparser解析是按嚴格的html標準解析,所以當碰到不標準的標簽有可能出錯,
當把以上這兩個參數改變以后,htmlparser解析不再嚴格,能應對所有可能出現的情況。