使用 Java 实现从搜索引擎批量下载图片

在进行一些数据收集、图像处理或研究工作时,我们可能需要从网络上批量下载高质量的图片。本文将介绍如何使用 Java 和 Jsoup 库,从搜索引擎中抓取图片,解析详情页并过滤出高质量图片。通过以下几个步骤,您可以自动化这个图片收集的过程。

前置条件

  • 环境 :确保您的开发环境配置了 Java 8+ 和 Jsoup 库。
  • 工具依赖 :引入 Jsoup 库,通过 MavenGradle 直接添加依赖。
xml 复制代码
<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.15.3</version>
</dependency>

基本思路

  1. 构建搜索 URL:通过搜索引擎构建一个带有关键字的查询 URL,限制结果为高分辨率图片。
  2. 解析搜索结果页面:获取所有图片链接或详情页链接。
  3. 进入详情页抓取大图:访问详情页,提取大图的真实 URL。
  4. 质量过滤与下载:根据图片尺寸、类型等条件,过滤并下载符合要求的图片。

步骤一:构建搜索 URL

搜索引擎提供了 URL 参数限制,我们可以添加关键字和图片大小筛选条件。以bing搜索为例,在 Bing 的 URL 中可以使用 imagesize-huge 参数过滤出大尺寸图片。例如:

java 复制代码
private static final String BASE_URL = "https://cn.bing.com/images/search?q=%s&form=ANNTH1&qft=+filterui:imagesize-huge";

其中 %s 为占位符,可动态替换为需要查询的关键字。

步骤二:解析搜索结果页面

使用 Jsoup 加载搜索结果页面并解析出所有图片的详情页链接。以下代码示例展示了如何提取搜索结果中的详情页链接:

java 复制代码
public static void downloadLargeImages(String searchValue) {
    try {
        String searchUrl = String.format(BASE_URL, searchValue);
        Document document = Jsoup.connect(searchUrl).get();

        // 选择所有带有详情链接的元素
        Elements linkElements = document.select("a[class*='item-link']"); //(以实际情况为准)

        int count = 0;
        for (Element linkElement : linkElements) {
            if (count >= 10) break;  // 设置下载数量上限

            // 获取详情页链接
            String detailPageUrl = linkElement.absUrl("href");
            if (!detailPageUrl.isEmpty()) {
                processDetailPage(detailPageUrl, count);
                count++;
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

步骤三:进入详情页抓取大图

在详情页中,通过 img 标签或特定属性来筛选大图的 URL。此处使用 img 标签的 src 属性,并进行其他属性检查,以确保我们下载的是大图而非缩略图。

java 复制代码
private static void processDetailPage(String detailPageUrl, int count) {
    try {
        Document detailPage = Jsoup.connect(detailPageUrl).get();
        
        // 查找所有 img 标签
        Elements imgElements = detailPage.select("img");
        for (Element imgElement : imgElements) {
            String imgUrl = imgElement.absUrl("src");

            // 过滤掉无效图片链接
            if (!imgUrl.startsWith("data:image/") && isHighQualityImage(imgUrl)) {
                downloadImage(imgUrl);
                break;
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

步骤四:质量过滤与下载

在下载图片前,确保图片符合质量要求(例如尺寸),避免下载不符合条件的小图或缩略图。我们可以使用 HTTP 请求获取图片的元数据或直接下载后通过 BufferedImage 获取尺寸信息:

java 复制代码
private static boolean isHighQualityImage(String imgUrl) {
    try {
        HttpURLConnection connection = (HttpURLConnection) new URL(imgUrl).openConnection();
        connection.setRequestMethod("GET");
        connection.connect();

        BufferedImage img = ImageIO.read(connection.getInputStream());
        if (img != null && img.getWidth() >= 800 && img.getHeight() >= 600) {
            return true;
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return false;
}

下载图片方法

使用 Java 的 ImageIO 将图片保存到本地,确保路径正确且避免重名文件。

java 复制代码
private static void downloadImage(String imgUrl) {
    try (InputStream in = new URL(imgUrl).openStream()) {
        Files.copy(in, Paths.get("downloaded_images/" + UUID.randomUUID() + ".jpg"));
        System.out.println("图片下载成功:" + imgUrl);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

完整代码

将以上方法整合,形成一个完整的批量图片下载程序。以下是完整的工作流程:

  1. 构建并发送搜索请求,获取搜索结果。
  2. 解析搜索结果页面,抓取每张图片的详情页 URL。
  3. 访问详情页,筛选符合条件的大图。
  4. 下载高质量图片并保存至本地。

总结

通过上述步骤,我们实现了一个简单的批量图片下载工具。整个过程涉及 URL 构建、HTML 解析、图片过滤和下载等多个步骤,适用于数据收集或批量处理需求。在实际应用中,建议加入适当的延迟控制访问频率,以避免触发搜索引擎的限制。

相关推荐
fire-flyer31 分钟前
Spring Boot 源码解析之 Logging
java·spring boot·spring·log4j·logging
papership36 分钟前
【入门级-C++程序设计:12、文件及基本读写-文件的基本概念&文本文件的基本操作】
开发语言·c++·青少年编程
SaleCoder2 小时前
用Python构建机器学习模型预测股票趋势:从数据到部署的实战指南
开发语言·python·机器学习·python股票预测·lstm股票模型·机器学习股票趋势
KoiHeng2 小时前
部分排序算法的Java模拟实现(复习向,非0基础)
java·算法·排序算法
cui_hao_nan5 小时前
JVM——如何对java的垃圾回收机制调优?
java·jvm
熟悉的新风景7 小时前
springboot项目或其他项目使用@Test测试项目接口配置-spring-boot-starter-test
java·spring boot·后端
心平愈三千疾7 小时前
学习秒杀系统-实现秒杀功能(商品列表,商品详情,基本秒杀功能实现,订单详情)
java·分布式·学习
玩代码7 小时前
备忘录设计模式
java·开发语言·设计模式·备忘录设计模式
BUTCHER58 小时前
Docker镜像使用
java·docker·容器
岁忧8 小时前
(nice!!!)(LeetCode 面试经典 150 题 ) 30. 串联所有单词的子串 (哈希表+字符串+滑动窗口)
java·c++·leetcode·面试·go·散列表