Java基礎知識:Jtidy解析腳本時候出現問題
最近在(zai)做網(wang)頁結構(gou)化(hua)信(xin)息抽(chou)取(qu),用到了JTidy和xslt.當在(zai)處理一些(xie)包含很多腳本的頁面時候,出現了,JTidy去臟(zang)失敗,提(ti)示標題中的異常。
最(zui)后發現,問(wen)題出現在解析腳本(ben)的時(shi)候因(yin)為一些腳本(ben)里面不規范的內容,導致不能(neng)判斷(duan)結束造成了上面的異常出現。
解決(jue)方法:
最初的(de)(de)時候想通(tong)過修改(gai)JTidy的(de)(de)源(yuan)(yuan)碼來解決這個(ge)問題,但是后來做著(zhu)發現可行性(xing)不高(gao),一(yi)個(ge)是修改(gai)這個(ge)源(yuan)(yuan)碼可能會帶(dai)來其它的(de)(de)問題。另外一(yi)個(ge),還要花(hua)長時間去看源(yuan)(yuan)碼。
所(suo)以,最終(zhong)還是選擇(ze)了采(cai)用預(yu)處理的方(fang)式來進(jin)行處理刪除掉腳本。
代(dai)碼
[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;
}
// 遞歸(gui)過濾(lv)
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;
}// 這里可以增加(jia)刪(shan)除的Tag
if (node instanceof StyleTag) {
list.remove(i);
continue;
}// 這(zhe)里可以增(zeng)加刪除的Tag
}
NodeList children = node.getChildren();
if (children != null && children.size() > 0)
visitNodeList(children);
}
}
但是在刪除腳本(ben)(ben)的(de)時(shi)候(hou)(hou)一樣遇到了(le)相(xiang)同的(de)問(wen)題,就是在解析腳本(ben)(ben)的(de)時(shi)候(hou)(hou)出現了(le)錯亂,把一些腳本(ben)(ben)中的(de)標簽識(shi)別(bie)為(wei)正常標簽。如:<script>里(li)面的(de) '<span></span>'里(li)面的(de)'</'就會被識(shi)別(bie)為(wei)腳本(ben)(ben)的(de)結(jie)束,導致腳本(ben)(ben)獲取不(bu)全,刪除不(bu)全最后在網上找到了(le)解決的(de)辦(ban)法通過下面兩(liang)個(ge)參(can)數的(de)設置來解析了(le)html對腳本(ben)(ben)的(de)處理問(wen)題
[java]
org.htmlparser.scanners.ScriptScanner.STRICT = false;
org.htmlparser.lexer.Lexer.STRICT_REMARKS = false;
只要配置(zhi)其中之一就(jiu)可以了,下(xia)面是這兩個參數的一個官方說明
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>.
*/
在默認情況(kuang)下(xia),htmlparser解析是按嚴(yan)格的html標準(zhun)解析,所以(yi)當碰(peng)到不標準(zhun)的標簽有可(ke)能出錯(cuo),
當把以上這兩個參數改(gai)變以后,htmlparser解析(xi)不再嚴格,能應對所(suo)有可能出現的情況。

您現在的位置: