在Java中正确加载网页HTML到字符串的最简单方法

30

正如标题所说。

非常感谢您的帮助!

3个回答

33
一个极为常见的错误是未能正确将HTTP响应从字节转换为字符。要做到这一点,您必须知道响应的字符编码。希望在“Content-Type”参数中指定此编码。但是,将其放在正文本身中,作为标记中的“http-equiv”属性也是一种选择。
因此,正确地将页面加载到字符串中实际上非常复杂,即使第三方库(如HttpClient)也没有提供通用解决方案。
以下是一个简单的实现,可以处理最常见的情况:
URL url = new URL("https://dev59.com/T3M_5IYBdhLWcg3wcCnc");
URLConnection con = url.openConnection();
Pattern p = Pattern.compile("text/html;\\s+charset=([^\\s]+)\\s*");
Matcher m = p.matcher(con.getContentType());
/* If Content-Type doesn't match this pre-conception, choose default and 
 * hope for the best. */
String charset = m.matches() ? m.group(1) : "ISO-8859-1";
Reader r = new InputStreamReader(con.getInputStream(), charset);
StringBuilder buf = new StringBuilder();
while (true) {
  int ch = r.read();
  if (ch < 0)
    break;
  buf.append((char) ch);
}
String str = buf.toString();

我知道这是一个非常老的问题,但如果您可以查看https://dev59.com/71vUa4cB1Zd3GeqPw83J,我会非常感激。 - dimo414
请将默认编码更改为“UTF-8”(http://trends.builtwith.com/encoding)。人们正在从您的(非常好的)答案中学习! - Tal Weiss
4
@TalWeiss 人气并不重要;ISO-8859-1 是指定的默认字符集。,“当发送者未提供明确的字符集参数时,'text' 类型的媒体子类型在通过 HTTP 接收时被定义为具有 'ISO-8859-1' 的默认字符集值。使用除 'ISO-8859-1' 或其子集以外的字符集中的数据必须标记适当的字符集值。” - erickson
3
我理解你的观点,但这是用于读取网页的代码,人们只想让他们的代码正常工作。就像你所说的“最好的希望”- 我不确定在未指定编码时你的代码实际工作的概率是多少。我猜想全球而言,使用UTF-8的成功率更高。 - Tal Weiss

4

您可以使用org.apache.commons.io.IOUtils进一步简化它:

URL url = new URL("https://dev59.com/T3M_5IYBdhLWcg3wcCnc");
URLConnection con = url.openConnection();
Pattern p = Pattern.compile("text/html;\\s+charset=([^\\s]+)\\s*");
Matcher m = p.matcher(con.getContentType());
/* If Content-Type doesn't match this pre-conception, choose default and 
 * hope for the best. */
String charset = m.matches() ? m.group(1) : "ISO-8859-1";
String str = IOUtils.toString(con.getInputStream(), charset);

1

我使用這個:

        BufferedReader bufferedReader = new BufferedReader( 
                                     new InputStreamReader( 
                                          new URL(urlToSeach)
                                              .openConnection()
                                              .getInputStream() ));

        StringBuilder sb = new StringBuilder();
        String line = null;
        while( ( line = bufferedReader.readLine() ) != null ) {
             sb.append( line ) ;
             sb.append( "\n");
        }
        .... in finally.... 
        buffer.close();

它大多数时候都有效。


结果字符串末尾将会有一个额外的“\n”。 - Tal Weiss

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接