如何在Java中以编程方式下载网页
如何以编程方式在Java中下载网页?
在Java中编程下载网页的原因是,有时我们可能希望对请求进行一些操作,如压缩或使用特定的用户代理。下面的代码演示了如何为请求添加不同类型的压缩。
URL url = new URL(urlStr); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // 强制转换不会失败 HttpURLConnection.setFollowRedirects(true); // 允许使用GZip和Deflate(ZLib)编码 conn.setRequestProperty("Accept-Encoding", "gzip, deflate"); String encoding = conn.getContentEncoding(); InputStream inStr = null; // 根据编码类型创建适当的流包装器 if (encoding != null && encoding.equalsIgnoreCase("gzip")) { inStr = new GZIPInputStream(conn.getInputStream()); } else if (encoding != null && encoding.equalsIgnoreCase("deflate")) { inStr = new InflaterInputStream(conn.getInputStream(), new Inflater(true)); } else { inStr = conn.getInputStream(); }
如果想要设置用户代理,可以添加以下代码:
conn.setRequestProperty ( "User-agent", "my agent name");
如果想要将InputStream转换为字符串,请参考此答案。
使用setFollowRedirects可以帮助避免一些问题,我在我的情况中使用了setInstanceFollowRedirects,之前在很多情况下得到的是空白页面。我认为你试图使用压缩来更快地下载文件。
如何在Java中以编程方式下载网页
问题的出现原因:
用户想要以编程方式下载网页,但不知道如何实现。
解决方法:
下面是使用Java的URL类的一些经过测试的代码。建议在处理异常时做得比我更好,或者将异常传递给调用堆栈。
public static void main(String[] args) { URL url; InputStream is = null; BufferedReader br; String line; try { url = new URL("http://stackoverflow.com/"); is = url.openStream(); // throws an IOException br = new BufferedReader(new InputStreamReader(is)); while ((line = br.readLine()) != null) { System.out.println(line); } } catch (MalformedURLException mue) { mue.printStackTrace(); } catch (IOException ioe) { ioe.printStackTrace(); } finally { try { if (is != null) is.close(); } catch (IOException ioe) { // nothing to see here } } }
DataInputStream.readLine()已被弃用,但除此之外,这是一个非常好的示例。我使用了包装在BufferedReader中的InputStreamReader()来获取readLine()函数。
此代码没有考虑字符编码,因此虽然它对于ASCII文本似乎可行,但最终会导致“奇怪的字符”,因为存在不匹配。
在第3行中,将DataInputStream
替换为BufferedReader
。并将"dis = new DataInputStream(new BufferedInputStream(is));"
替换为"dis = new BufferedReader(new InputStreamReader(is));"
谢谢!我更新了我的答案,删除了对弃用方法的调用。
对于关闭InputStreamReader
怎么处理呢?
如果需要将所有行放在一起,使用StringBuilder的append("line")方法而不是System.out.println(line) - 这将是将所有行放在一起的最有效方法。
这段代码没有关闭它的套接字。
问题的出现原因:作者想要在Java中以编程方式下载网页,但是不知道应该如何实现。
解决方法:使用Jsoup这个HTML解析器,可以轻松地实现网页下载。代码如下:
String html = Jsoup.connect("http://stackoverflow.com").get().html();
Jsoup可以处理GZIP和chunked响应以及字符编码,具有透明性。它还提供了更多的优势,例如HTML遍历和通过CSS选择器的操作,类似于jQuery的功能。只需将其作为Document对象获取,而不是字符串。
Document document = Jsoup.connect("http://google.com").get();
最好不要在HTML上运行基本的字符串方法甚至使用正则表达式进行处理。
此外,还有一个相关的问题链接,讨论了Java中领先的HTML解析器的优缺点。并且还有一些其他的评论和提示,例如在Android中使用Jsoup时需要在不同的线程中使用,以避免抛出NetworkOnMainThreadException的异常。