关于 htmlparser Parser 的编码问题

时间:2022-11-10 18:08:51
我在使用htmlparser来解析HTML,但是使用中发现重新设置编码有问题。

final Parser parser = new Parser("https://forum.csdn.net/");
parser.setEncoding("utf-8");
就是这里的 setEncoding ,应该与Parser解析的页面的编码一致。
由于有的页面是gb2312,有的是utf-8,还有其他的,因此从页面获取编码
但是parser.getEncoding()返回值有问题,因此我自己做了一个resetCharset()方法getEncoding()

    String charset = "gb2312";
    public void resetCharset(final Parser parser) {
        final String CHARSET_STRING = "charset";
        try
        {
            parser.setEncoding(this.charset);
            final NodeFilter metaFilter = new NodeClassFilter(MetaTag.class);
            final NodeList meta = parser.extractAllNodesThatMatch(metaFilter);
            for (int i = 0; i < meta.size(); i++)
            {
                final MetaTag metaTag = (MetaTag) meta.elementAt(i);
                if ((metaTag.getAttribute("http-equiv") != null) && (metaTag.getAttribute("http-equiv").equalsIgnoreCase("content-type")))
                {
                    String content = metaTag.getAttribute("content");
                    if (null != content)
                    {
                        int index = content.toLowerCase().indexOf(CHARSET_STRING);

                        if (index != -1)
                        {
                            //下面这一段 org.htmlparser.lexer.page.getCharset()
                            content = content.substring(index + CHARSET_STRING.length()).trim();
                            if (content.startsWith("="))
                            {
                                content = content.substring(1).trim();
                                index = content.indexOf(";");
                                if (index != -1)
                                {
                                    content = content.substring(0, index);
                                }
                                if (content.startsWith("\"") && content.endsWith("\"") && (1 < content.length()))
                                {
                                    content = content.substring(1, content.length() - 1);
                                }

                                if (content.startsWith("'") && content.endsWith("'") && (1 < content.length()))
                                {
                                    content = content.substring(1, content.length() - 1);
                                }
                            }
                            this.charset = content;
                        }
                    }
                }
            }
        }
        catch (final Exception e)
        {
            e.printStackTrace();
        }
    }

这样开始的代码就应该是:
final Parser parser = new Parser("https://forum.csdn.net/");
this.resetCharset(parser);
parser.setEncoding(this.charset); //TestPage.java:Line 102

但这个时候报
org.htmlparser.util.ParserException: reset stream failed
at org.htmlparser.lexer.InputStreamSource.setEncoding(InputStreamSource.java:277)
at org.htmlparser.lexer.Page.setEncoding(Page.java:865)
at org.htmlparser.Parser.setEncoding(Parser.java:478)
at TestPage.test2(TestPage.java:102)
at TestPage.main(TestPage.java:20)

很郁闷呀,请各位大侠帮忙!

8 个解决方案

#1


帮顶

#2


我知道有这样的方法:
parser.setEncoding(parser.getEncoding());
但是我发现这个设定的值不是我想要的值,它设定的都是默认值:ISO-8859-1
我想这是个BUG,我的版本是htmlparser1.6。

#3


试试这样定义:
Parser parser = Parser.createParser("https://forum.csdn.net/" , "gb2312");

#4


3楼的意思还是要先指定编码。
我遇到这样的问题,有些网页是unicode编码,用gb2312就乱码;有些是GBK的,用gb2312也乱码;有些gb2312用GBK也乱码。因此我肯定不能自己指定编码,应该用它原有的编码,但是parser.setEncoding(parser.getEncoding())就是得不到它的编码。我用的是htmlparser1.6,不知道其他版本有没有这样的问题。

#5


呜呜,自己顶

#6


这个问题我也遇到过,不知道是不是一个bug,有一种方法可以解决,你可以先把网页的html从目标url下载下来,
放到一个sting对象里面,然后用这个string对象作为参数实例化Parser就可以了!

关于如何获取html,我可以给你一个类,我自己写的,仅供参考:
package util;
import java.net.MalformedURLException;
public class URLInputStream {
public java.net.URL inputURL;

public URLInputStream(String strUrl) throws MalformedURLException
{
this.inputURL=new java.net.URL(strUrl);
}

@SuppressWarnings("finally")
public String getHtml()
{

StringBuffer sbHtml=new StringBuffer();
String strHtml=null;
java.io.InputStream httpInputStream=null;
try{
httpInputStream=this.inputURL.openStream();
java.io.InputStreamReader httpInputStreamReader=new java.io.InputStreamReader(httpInputStream);
java.io.BufferedReader httpBufferedReader=new java.io.BufferedReader(httpInputStreamReader);
while((strHtml=httpBufferedReader.readLine())!=null)
sbHtml.append(strHtml+"\n");
}
catch(Exception ex)
{
javax.swing.JOptionPane.showMessageDialog(null, ex.toString());
sbHtml.delete(0, sbHtml.length()-1);

}
finally
{
try{
httpInputStream.close();
}
catch(final Exception ex)
{
javax.swing.JOptionPane.showMessageDialog(null, ex.toString());
}
finally
{
return new String(sbHtml);
}
}


}
}


#7


这个已经放弃了
不过,最近我在项目管理的时候,发现一个东西可以试试,只是没有时间试,jchardet可以用来猜测html文件编码,如果这个能够正确获取编码,下面的问题就简单了。

这个帖子等等再关闭吧

#8


哎 ,, 我今天也碰到这个问题了 可纳闷了...

#1


帮顶

#2


我知道有这样的方法:
parser.setEncoding(parser.getEncoding());
但是我发现这个设定的值不是我想要的值,它设定的都是默认值:ISO-8859-1
我想这是个BUG,我的版本是htmlparser1.6。

#3


试试这样定义:
Parser parser = Parser.createParser("https://forum.csdn.net/" , "gb2312");

#4


3楼的意思还是要先指定编码。
我遇到这样的问题,有些网页是unicode编码,用gb2312就乱码;有些是GBK的,用gb2312也乱码;有些gb2312用GBK也乱码。因此我肯定不能自己指定编码,应该用它原有的编码,但是parser.setEncoding(parser.getEncoding())就是得不到它的编码。我用的是htmlparser1.6,不知道其他版本有没有这样的问题。

#5


呜呜,自己顶

#6


这个问题我也遇到过,不知道是不是一个bug,有一种方法可以解决,你可以先把网页的html从目标url下载下来,
放到一个sting对象里面,然后用这个string对象作为参数实例化Parser就可以了!

关于如何获取html,我可以给你一个类,我自己写的,仅供参考:
package util;
import java.net.MalformedURLException;
public class URLInputStream {
public java.net.URL inputURL;

public URLInputStream(String strUrl) throws MalformedURLException
{
this.inputURL=new java.net.URL(strUrl);
}

@SuppressWarnings("finally")
public String getHtml()
{

StringBuffer sbHtml=new StringBuffer();
String strHtml=null;
java.io.InputStream httpInputStream=null;
try{
httpInputStream=this.inputURL.openStream();
java.io.InputStreamReader httpInputStreamReader=new java.io.InputStreamReader(httpInputStream);
java.io.BufferedReader httpBufferedReader=new java.io.BufferedReader(httpInputStreamReader);
while((strHtml=httpBufferedReader.readLine())!=null)
sbHtml.append(strHtml+"\n");
}
catch(Exception ex)
{
javax.swing.JOptionPane.showMessageDialog(null, ex.toString());
sbHtml.delete(0, sbHtml.length()-1);

}
finally
{
try{
httpInputStream.close();
}
catch(final Exception ex)
{
javax.swing.JOptionPane.showMessageDialog(null, ex.toString());
}
finally
{
return new String(sbHtml);
}
}


}
}


#7


这个已经放弃了
不过,最近我在项目管理的时候,发现一个东西可以试试,只是没有时间试,jchardet可以用来猜测html文件编码,如果这个能够正确获取编码,下面的问题就简单了。

这个帖子等等再关闭吧

#8


哎 ,, 我今天也碰到这个问题了 可纳闷了...