使用I/O流下载网络图片

141 阅读1分钟

介绍

这里用某乎举例,通过输入某乎网址,自动下载里面的图片

分为两个部分:

  • 获取图片的链接
  • 下载图片

代码

第一部分:获取图片的链接

使用URL对象连接到网页,这里通过url.openStream()获取输入流读取页面的信息,一次读取一行,通过正则表达式匹配到需要的图片地址,然后保存到集合中返回

正则表达式:(lightbox-thumb lazy\".+?data-original=\")((https://[\\w-./_]+jpg\\?source=[\\w]{8})|(https://[\\w-./_]+jpg))(?=\")

/**
 * 查找页面下的图片
 *
 * @param urlStr 页面链接
 * @return ArrayList
 */
public static ArrayList<String> webCrawler(String urlStr) throws IOException {
    // 读取页面的信息(H5信息)
    URL url = new URL(urlStr);
    BufferedReader inputStream = new BufferedReader(new InputStreamReader(url.openStream()));
    // 查找规则
    String pattern = "(lightbox-thumb lazy\".+?data-original=\")" +
            "((https://[\\w-./_]+jpg\\?source=[\\w]{8})|(https://[\\w-./_]+jpg))" +
            "(?=\")";
    Pattern compile = Pattern.compile(pattern);
    // 存储图片地址
    ArrayList<String> imagesURL = new ArrayList<>();
    // 查找图片
    String line;
    while ((line = inputStream.readLine()) != null) {
        Matcher matcher = compile.matcher(line);
        while (matcher.find()) {
            String imgUrl = matcher.group(2);
            imagesURL.add(imgUrl);
        }
    }
    inputStream.close();
    return imagesURL;
}

第二部分:下载图片

原理很简单,就是通过URL对象连接图片url地址,然后使用其openStream()方法获取一个输入流读取图片数据,最后使用输出流保存到本地既可,文件名可以使用时间戳命名

/**
 * 功能描述: 下载图片
 *
 * @param urlList 图片url地址
 * @param testPath 要下载到的目标路径
 */
public static void downloadPicture(ArrayList<String> urlList, String testPath) throws IOException {
    if (urlList == null) {
        throw new RuntimeException("没有图片");
    }
    // 创建文件夹(文件夹可能不存在,所以创建一个文件夹比较保险)
    File file = new File(testPath);
    boolean mkdirs = file.mkdirs();
    // 下载图片
    for (String urlStr : urlList) {
        // 通过创建URL对象,调用openStream()获取一个输入流读取网络图片
        URL url = new URL(urlStr);
        BufferedInputStream input = new BufferedInputStream(url.openStream());
        BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(currentFileName(testPath)));
        try (input; output) {
            int len;
            byte[] bytes = new byte[1024];
            while ((len = input.read(bytes)) != -1) {
                output.write(bytes, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
/**
 * 创建下载的目标路径,路径+文件名
 * 文件名使用时间戳命名
 */
public static String currentFileName(String testPath){
    StringBuilder builder = new StringBuilder(testPath);
    long timeMillis = System.currentTimeMillis();
    String suffix = ".jpg";
    return builder.append("\知乎_").append(timeMillis).append(suffix).toString();
}

运行代码