当前位置: 首页 > news >正文

批量抓取图片

本文为个人学习笔记整理,仅供交流参考,非专业教学资料,内容请自行甄别。
通过学习获取的图片仅可用于个人技术研究(如测试下载逻辑、解析代码),不得用于商业用途(如制作产品素材、二次分发),也不能传播涉及版权或隐私的内容。

文章目录

  • 前言
  • 一、批量抓取图片
    • 1.1、概述
    • 1.2、项目运用


前言

  本文主要介绍如何运用第三方图片搜索引擎,实现批量获取图片的功能。本篇中使用bing的实现。

一、批量抓取图片

1.1、概述

  使用bing进行图片批量抓取,基础的访问链接:

https://cn.bing.com/images/async?q=xxx

  q=是必需参数,用于指定搜索关键词,此外还有一些常见的可选参数:

  • first:可选参数,用于指定从第几张图片开始返回,用于分页,如first=35表示从第 35 张图片开始返回。
  • count:可选参数,用于控制返回的搜索结果数量,默认值可能为 35,最大值一般为 150,如count=20表示返回 20 张图片。
  • cw和ch:可选参数,可能用于指定图片的宽度和高度,如cw=1177&ch=737。
  • mmasync:可选参数,可能用于控制异步加载的某种机制,一般设置为 1。

  在浏览器上访问:
在这里插入图片描述
在这里插入图片描述
  按下F12进行观察,发现返回的是html格式的文本,还需要再次进行解析。
在这里插入图片描述
  在Java中,可以通过正则表达式,或者引入第三方的库再次进行解析,这里推荐使用jsoup

        <!-- HTML 解析:https://jsoup.org/ --><dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.15.3</version></dependency>

  在项目中通过jsoup的api发送请求,然后对Document实例进行解析,得到搜索结果的html中真正的图片地址,然后就可以保存到本地或者上传到第三方的存储空间中了。
在这里插入图片描述

1.2、项目运用

  在项目中的运用,总体设计为,前端页面让用户填写抓取的关键词数量,以及批次
在这里插入图片描述
  后端使用DTO进行接收:

@Data
public class PictureUploadByBatchRequest {/*** 搜索词*/private String searchText;/*** 抓取数量*/private Integer count = 5;/*** 执行批次*/private Integer batch = 1;
}

  后端的设计思路是加入一个图片抓取记录表,主要用于记录某个搜索关键字的当前偏移量,表结构设计,最终图片是上传到腾讯云对象存储中。

create table first.picture_fetch_record
(id            bigint                             not null comment '主键Id'primary key,keyWord       varchar(255)                       null comment '搜索关键词',currentOffset int                                null comment '当前搜索偏移量',userId        bigint                             null comment '操作人id',createTime    datetime default CURRENT_TIMESTAMP not null comment '创建时间',updateTime    datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间'
)comment '图片抓取记录表';

  service层完整实现如下:

    @Overridepublic Integer adminFetchPicture(PictureUploadByBatchRequest pictureUploadByBatchRequest, HttpServletRequest httpServletRequest) {String searchText = pictureUploadByBatchRequest.getSearchText();Integer count = pictureUploadByBatchRequest.getCount();Integer batch = pictureUploadByBatchRequest.getBatch();//        ThrowUtils.throwIf(count > 30, ErrorCode.OPERATION_ERROR, "批量获取图片,不能超过30张");
//        ThrowUtils.throwIf(batch > 6, ErrorCode.OPERATION_ERROR, "批量获取图片,批次不能超过6批");User loginUser = userService.getLoginUser(httpServletRequest);int totalCount = 0;for (Integer i = 0; i < batch; i++) {//首先查询该关键字有无搜索记录PictureFetchRecord pictureFetchRecord= pictureFetchRecordService.lambdaQuery().eq(PictureFetchRecord::getKeyWord, searchText).one();// 要抓取的地址String fetchUrl = String.format("https://cn.bing.com/images/async?q=%s&mmasync=1&first=%s", searchText,ObjUtil.isEmpty(pictureFetchRecord) ? 1 : pictureFetchRecord.getCurrentOffset() + count);//解析documentDocument document;try {document = Jsoup.connect(fetchUrl).get();} catch (IOException e) {log.error("获取页面失败", e);throw new BusinessException(ErrorCode.OPERATION_ERROR, "获取页面失败");}Element div = document.getElementsByClass("dgControl").first();if (ObjUtil.isNull(div)) {throw new BusinessException(ErrorCode.OPERATION_ERROR, "获取元素失败");}Elements imgElementList = div.select("img.mimg");int uploadCount = 0;for (Element imgElement : imgElementList) {String fileUrl = imgElement.attr("src");if (StrUtil.isBlank(fileUrl)) {log.info("当前链接为空,已跳过: {}", fileUrl);continue;}// 处理图片上传地址,防止出现转义问题int questionMarkIndex = fileUrl.indexOf("?");if (questionMarkIndex > -1) {fileUrl = fileUrl.substring(0, questionMarkIndex);}PictureUploadRequest pictureUploadRequest = new PictureUploadRequest();try {pictureUploadRequest.setPicName(searchText + "(" + System.currentTimeMillis() + ")");// 上传图片PictureVO pictureVO = this.uploadPicture(fileUrl, pictureUploadRequest, loginUser);log.info("图片上传成功, id = {}", pictureVO.getId());uploadCount++;totalCount++;} catch (Exception e) {log.error("图片上传失败", e);continue;}if (uploadCount >= count) {break;}}if (ObjUtil.isEmpty(pictureFetchRecord)){PictureFetchRecord record = new PictureFetchRecord();record.setKeyWord(searchText);record.setUserId(loginUser.getId());record.setCurrentOffset(1);pictureFetchRecordService.save(record);}else {pictureFetchRecord.setCurrentOffset(pictureFetchRecord.getCurrentOffset() + count);pictureFetchRecordService.updateById(pictureFetchRecord);}}return totalCount;}
http://www.dtcms.com/a/393206.html

相关文章:

  • WinDivert学习文档之五-————编程API(十一)
  • 【打印菱形】
  • XC7Z100-2FFG900I Xilinx AMD Zynq-7000 FPGA SoC
  • 成本价的SEO优化服务供应链
  • dock生命周期体验-生到死的命令
  • 软件测试方案-模板一
  • 防火墙WEB方式登录配置【HCL模拟】-学习篇(1)
  • Ceph用户管理与cephFS分布式存储实战
  • AgenticSeek:重新定义AI助手的边界 - 100%本地化智能代理系统深度解析
  • 701. 二叉搜索树中的插入操作
  • Spring AI(六)Tool Calling本地回调方法
  • 《2511系统分析师第二遍阅读总结3》
  • 【Linux】系统部分——线程同步与生产者消费者模型
  • No008:共建产业知识生态——DeepSeek如何助力中小企业数字化转型
  • 3.8 开发环境 - IntelliJ IDEA
  • Paimon系列:IDEA环境读写Paimon表
  • Java进阶教程,全面剖析Java多线程编程,插入线程,笔记10
  • 成品油加油站综合服务智慧监管平台! “智控油站,计量秒核查” + “数治加油,科技防猫腻”
  • C++编程学习(第34天)
  • 【数据结构与算法Trip第5站】动态规划
  • 防抖那些事儿
  • 【办公类-115-01】20250920信息员每周通讯上传之文字稿整理
  • 深入解析HotSpot解释器方法调用机制:从invokevirtual到方法入口
  • 用AI修复失语者的声音:大模型如何帮助渐冻人重新“说话”?
  • 【ICCV 2023】通过学习采样来学习上采样
  • 有效解决舍入误差的方法
  • count down 90 days
  • GEO完全指南 AI时代的内容优化新范式
  • Npass gate transistor是什么器件?
  • TensorRT-LLM中的in-flight batching(IFB)