Java抓取网页图片并保存到本地(HTTPS)
下面仅介绍用添加安全证书的方式,下载HTTPS网页图片到本地
一,下载网页安全证书到本地
以Chrome为例,打开相关网站,在地址栏的锁图标上单击,再单击【连接是安全的】-》【证书有效】-》【详细信息】-》【复制到文件】,将证书以默认格式保存到本地。本文以khl.cer为例。
二,导入证书到本地keystore
Windows10中,按【Win+X】,选择【Windows终端(管理员)】,以管理员运行PowerShell,在窗口中,先切换到JAVA_HOME\jre\bin目录,本文是C:\Java\jdk1.8.0_144\jre\bin
注意:如果路径有空格,请在路径上加上引号
然后执行导入命令:
keytool -import -v -trustcacerts -alias my_cert -file D:\TDDOWNLOAD\khl.cer -storepass changeit -keystore "C:\Java\jdk1.8.0_144\jre\lib\security\cacerts"
如果路径有不同,请做相应更改。整体效果如下图,在问及是否信任此证书时,输入【y】
三,Java实现代码
注意,请直接参考代码中的startDownload方法即可。本程序是实现将网站上的图片全部抓取下来的(图片地址存储于MySQL数据库中)
package com.clzhang.sample.net; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.List; public class DownloadImgFromKHL { // 数据库配置信息,注意:MySQL8的JDBC URL不同于之前版本 public static final String MYSQL_JDBC_URL = "jdbc:mysql://localhost:3306/jhl?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8&useSSL=false"; /** * 主处理程序 * * @throws Exception */ public void process() throws Exception { // MySQL8开始,用如下类进行处理;数据库的用户名与密码,不要存放到JDBC URL中,而是在获取连接时加入 Class.forName("com.mysql.cj.jdbc.Driver"); // 数据库连接句柄 Connection conn = null; String SELECT_SQL = "select id,image1,image2,image3,image4,image5 from lfdata where id>? order by id asc"; try { conn = DriverManager.getConnection(MYSQL_JDBC_URL, "root", "admin"); PreparedStatement pstmt = conn.prepareStatement(SELECT_SQL); pstmt.setInt(1, 44561); ResultSet rs = pstmt.executeQuery(); while (rs.next()) { List<String> listImg = new ArrayList<String>(); String id = rs.getString("id"); String image1 = rs.getString("image1"); String image2 = rs.getString("image2"); String image3 = rs.getString("image3"); String image4 = rs.getString("image4"); String image5 = rs.getString("image5"); if (image1 != null && image1.length() > 0) listImg.add(image1); if (image2 != null && image2.length() > 0) listImg.add(image2); if (image3 != null && image3.length() > 0) listImg.add(image3); if (image4 != null && image4.length() > 0) listImg.add(image4); if (image5 != null && image5.length() > 0) listImg.add(image5); startDownload(listImg); System.out.println(id); } rs.close(); pstmt.close(); } finally { // TODO: handle finally clause if (conn != null) conn.close(); } } private void startDownload(List<String> listImg) { try { for (String strURL : listImg) { System.out.println(strURL); String imageName = "D:\\TDDOWNLOAD\\uploads\\" + strURL.substring(strURL.lastIndexOf("/") + 1, strURL.length()); URL url = new URL(strURL); URLConnection conn = url.openConnection(); //设置超时间为3秒 conn.setConnectTimeout(3 * 1000); //防止屏蔽程序抓取而返回403错误 conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)"); //输出流 InputStream str = conn.getInputStream(); //控制流的大小为1k byte[] bs = new byte[1024]; //读取到的长度 int len = 0; //是否需要创建文件夹 File file = new File(imageName); //实例输出一个对象 FileOutputStream out = new FileOutputStream(file); //循环判断,如果读取的个数b为空了,则is.read()方法返回-1,具体请参考InputStream的read(); while ((len = str.read(bs)) != -1) { //将对象写入到对应的文件中 out.write(bs, 0, len); } //刷新流 out.flush(); //关闭流 out.close(); str.close(); } } catch (Exception ex) { ex.printStackTrace(); } } public static void main(String[] args) throws Exception { DownloadImgFromKHL ins = new DownloadImgFromKHL(); ins.process(); } }