作者PsMonkey (痞子军团团长)
看板java
标题Re: [工具] HtmlParser 的一些白痴心得
时间Mon Aug 6 18:23:59 2007
※ 引述《archerlin ()》之铭言:
: 之前我也有使用过htmlparser的经验
: 但我觉得网页的编码始终是个大问题耶
: 因为世界上的网页千奇百怪
: 不按照牌理出牌(不按规范编写)的html实在不胜枚举
: 不成双成对的tag,没有任何META宣告的网页
: 造成抓取上的判读和字型解码相对困难许多
: 我的应用比较简单,只是想要抓网页的标题存成字串
: (就是每个网页在浏览器最上方的title标题那行字)
: 运用他的 TagNameFilter(tagName) 来达到目的,例如:
: String tittleName = parseTag(url, "title");
我觉得用
ObjectFindingVisitor visitor = new ObjectFindingVisitor(TitleTag.class);
parser.visitAllNodesWith(visitor);
看起来会比你的简单而且好读的多
: 但我第一次抓取时不管怎麽怎麽写都会跳出 ParserException
: 也抓不到我想要的标题字串,後来发现原来是网页编码上的问题
: 经由不断地反覆的测试和参考了官方网站的FAQ之後
: 改写成下面这样:
: public static String parseTag(String url, String tagName) {
: String ret = "网页没有预设标题";
: try {
: Parser parser = new Parser(url);
: try {
: // first todo parser.parse(...);
: // maybe throws an EncodingChangeException...
: ret = parser.parse(new TagNameFilter(tagName))
: .asString();
: } catch (EncodingChangeException ece) {
: try {
: // reset the parser
: parser.reset();
: // try again with the encoding now in force
: // second parser.parse (...);
: ret = parser.parse(new TagNameFilter(tagName))
: .asString();
: } catch (ParserException pe) {
: pe.printStackTrace();
: }
: }
基本上,他的 Site Capturer 也是这样子搞
所以,不要太难过... [拍拍]
: 如上所示,包两层的try...catch...
: 透过两次的second parser才能真正得到我想要的字串回传
: 传回的字串也能有"大约90%"的成功机率不会是乱码...
: 为啥还是有10%的失败率呢?後来我分析原因
: 发现失败的网站大多没有写这行(或有写但编码写错了)
: <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
: 估计他抓不到 charset 这个属性所以就无法判读出该网页到底是啥编码了
: 导致我要手动的再去做转码的动作
: 例如在
: String tittleName = parseTag(url, "title");
: 之後,在META无指定charset的中文网页需多做这行
: tittleName = new String(tittleName.getBytes("ISO-8859-1"),"BIG5");
: 在META无指定charset的日文网页需多执行这行...依此类推
: tittleName = new String(tittleName.getBytes("ISO-8859-1"),"Shift-JIS");
: 不知道版上的高手有无啥解决方案,能够准确的判定该网页的编码阿?
: 至於一些框架页面,多重转址页面,一些稀奇古怪的网页,抓不到就算了 XD
精准... 是不太可能的
就像这个网页,只能说... 高义! 你 [哔—]
http://fanqiang.chinaunix.net/a4/b5/20011230/08300025_b.html
不过,你的解法实在不怎麽妙...
毕竟,也有中文网页是 UTF-8 [指]
而且...
以我知道的,连一个 url 可以得知编码的地方有几个
→HttpConnection.getContentEncoding()
→HttpConnection.getContentType()
→HTML 当中的 meta tag,找寻 content-type 的 value
第一个,以我目前遇到的... 嗯... 基本上都是 null
所以,基本上好像可以忽略 Orz
後面两个,是取 charset= 後头的字串。
如果上面三个都没办法给编码的资讯,我预设的编码是 UTF-8
扣掉 IE 跟 firefox 开起来也是乱码的网页
(向上面那个高义网页... Orz)
中文(繁简)编码正确率大概 90% (咦....)
--
侃侃长论鲜窒碍 首页:
http://www.psmonkey.idv.tw
众目睽睽无心颤 Blog:
http://ps-think.blogspot.com
茕居少聊常人事
杀头容易告白难 欢迎参观 Java 版(@ptt.cc) \囧/
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 61.228.193.251