利用Python爬虫实现百度图片搜索的PNG图片下载

在图像识别、训练数据集构建等场景中,我们经常需要从互联网上批量下载图片素材。百度图片是中文搜索中最常用的来源之一。本文将介绍如何使用Python构建一个稳定、可扩展的百度图片爬虫,专门用于下载并保存高清PNG格式图片。

一、项目目标

本项目的目标是:

  • 自动从百度图片搜索指定关键词

  • 下载所有可用图片并统一转换为PNG格式

  • 支持分页下载,避免重复图片

  • 稳定运行,具备错误处理能力

  • 自动过滤无效链接和非图像内容

二、关键依赖

主要依赖的Python库如下:

  • requests:用于发起HTTP请求

  • Pillow (PIL):图像格式识别与转换

  • hashlib:用于生成唯一文件名

  • io:处理图片内容流

  • jsonostime 等标准库

三、爬虫结构设计

1. 接口分析

百度图片新版接口为:百度图片 | 免费AI图像生成工具与海量高清图平台
分页机制基于参数 pn(当前起始项索引)和 gsm(页面校验字段),每页默认返回30条结果。

2. 核心流程

完整流程如下:

  1. 构造请求头和参数,模拟浏览器访问行为

  2. 获取搜索结果的JSON响应

  3. 提取每张图片的有效URL(优先高清地址)

  4. 验证URL有效性并请求下载

  5. 判断是否为PNG格式,非PNG则使用Pillow进行转换

  6. 利用图片内容计算MD5,避免重复保存

  7. 统一保存为PNG格式到本地指定目录

3. 文件去重机制

使用 hashlib.md5 计算图片二进制内容的哈希值作为文件名,确保即使同一张图片来自不同URL也不会重复保存。

四、异常与边界处理

为了保证稳定运行,代码中加入了如下处理机制:

  • 请求超时控制,防止因单张图片卡死

  • 图片类型校验,跳过非图像内容

  • JSON解析失败自动保存错误响应

  • URL合法性检查,避免处理无效链接

  • Pillow转换异常捕获,跳过无法解析的图片

五、转换逻辑详解

如果下载的图片不是PNG格式,会自动使用 Pillow 转换:

  • 如果是 P, LA 模式,转换为 RGBA

  • 如果是 CMYK,转换为 RGB

  • 所有图片统一保存为 .png 格式,适用于图像训练、压缩优化等应用场景

六、运行效果示例

以关键词“风景”为例,设置 max_pages=3,即可抓取约90张图片,转换并保存为高清PNG文件。脚本自动等待每页完成后延迟5秒,降低被封风险。

七、完整代码入口

脚本如下所示:

import requests
import os
import time
import hashlib
import json
import io
from urllib.parse import unquote
from PIL import Image  # 需要安装Pillow库:pip install Pillowdef download_baidu_png_images(query, max_pages=3, save_dir='./data'):"""下载百度图片搜索结果并确保保存为PNG格式(自动转换非PNG图片)"""# 创建保存目录os.makedirs(save_dir, exist_ok=True)# 更新请求头headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 Edg/118.0.2088.46','Referer': 'https://image.baidu.com/','Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8'}# 新版请求参数base_url = 'https://image.baidu.com/search/acjson'downloaded = 0  # 成功下载计数器for page in range(max_pages):try:# 生成动态参数pn = page * 30gsm = hex(50 + page)[2:]  # 生成动态gsm参数params = {'tn': 'resultjson_com','ipn': 'rj','ct': 201326592,'is': '','fp': 'result','queryWord': query,'cl': 2,'lm': -1,'ie': 'utf-8','oe': 'utf-8','adpicid': '','st': -1,'z': '','ic': '','hd': '','latest': '','copyright': '','word': query,'s': '','se': '','tab': '','width': '','height': '','face': 0,'istype': 2,'qc': '','nc': 1,'fr': '','expermode': '','pn': pn,'rn': 30,'gsm': gsm,'time': int(time.time() * 1000)}response = requests.get(base_url, headers=headers, params=params, timeout=15)response.encoding = 'utf-8'print(f"第 {page + 1} 页响应状态码:{response.status_code}")try:data = json.loads(response.text.strip().replace("\\'", "'"))except Exception as e:print(f"JSON解析失败:{str(e)}")with open('error.json', 'w', encoding='utf-8') as f:f.write(response.text)print("已保存错误响应到error.json")continue# 调试:打印数据长度print(f"获取到 {len(data.get('data', []))} 条数据")for index, item in enumerate(data.get('data', [])):if not isinstance(item, dict):continue# 优先获取高清图片URLimg_url = item.get('hoverURL') or item.get('thumbURL') or item.get('middleURL')if not img_url:# 处理加密的objURLif 'objURL' in item:try:img_url = unquote(item['objURL']).split('src=')[-1].split('&')[0]except:continueif not img_url:print(f"第 {index} 条记录未找到有效URL")continue# URL有效性检查if not img_url.startswith(('http://', 'https://')):print(f"无效的URL格式:{img_url[:50]}...")continuetry:# 增加图片下载超时时间img_res = requests.get(img_url, headers=headers, timeout=(10, 20))if img_res.status_code != 200:print(f"下载失败:HTTP {img_res.status_code} - {img_url[:50]}...")continue# 增强文件类型验证content_type = img_res.headers.get('Content-Type', '')if 'image' not in content_type:print(f"非图片内容:{content_type} - {img_url[:50]}...")continue# 验证是否为PNG格式is_png = Falseif len(img_res.content) >= 8:png_signature = img_res.content[:8]is_png = png_signature.startswith(b'\x89PNG\r\n\x1a\n') or png_signature[:4] == b'\x89PNG'if is_png:# 直接保存PNGfile_hash = hashlib.md5(img_res.content).hexdigest()filename = os.path.join(save_dir, f"{file_hash}.png")if not os.path.exists(filename):with open(filename, 'wb') as f:f.write(img_res.content)downloaded += 1print(f"成功保存PNG:{filename}")else:print(f"PNG文件已存在:{filename}")else:# 转换其他格式为PNGtry:image = Image.open(io.BytesIO(img_res.content))# 处理图像模式if image.mode in ('P', 'LA'):image = image.convert('RGBA')elif image.mode == 'CMYK':image = image.convert('RGB')# 保存转换后的PNG到内存img_byte_arr = io.BytesIO()image.save(img_byte_arr, format='PNG')converted_content = img_byte_arr.getvalue()# 计算哈希并保存file_hash = hashlib.md5(converted_content).hexdigest()filename = os.path.join(save_dir, f"{file_hash}.png")if not os.path.exists(filename):with open(filename, 'wb') as f:f.write(converted_content)downloaded += 1print(f"转换保存PNG:{filename}(原始格式:{image.format})")else:print(f"PNG文件已存在:{filename}")except Exception as convert_error:print(f"格式转换失败:{img_url[:50]}... 错误:{str(convert_error)}")continueexcept Exception as e:print(f"下载失败:{img_url[:50]}... 错误:{str(e)}")continueprint(f"第 {page + 1} 页处理完成,累计下载 {downloaded} 张图片,等待5秒...")time.sleep(5)except Exception as e:print(f"页面处理异常:{str(e)}")continueprint(f"\n总计下载 {downloaded} 张PNG图片")if __name__ == '__main__':download_baidu_png_images(query="风景",  # 修改搜索关键词max_pages=100,  # 爬取页数save_dir='./data'  # 保存目录)

八、结语

百度图片爬虫本身并不复杂,但需要考虑接口变化、图片格式处理、反爬机制应对等实际问题。通过合理的结构设计和充分的异常处理,我们可以构建一个稳定、高效的图片抓取工具,为深度学习和计算机视觉项目打下数据基础。

如需进一步改造为模块化、多线程或封装为API服务,也可以在当前框架上快速拓展。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/902729.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Axure复选框组件的深度定制:实现自定义大小、颜色与全选功能

在产品设计中,复选框作为用户与界面交互的重要元素,其灵活性直接影响到用户体验。本文将介绍如何利用Axure RP工具,通过高级技巧实现复选框组件的自定义大小、颜色调整,以及全选功能的集成,为产品原型设计增添更多可能…

深度理解spring——BeanFactory的实现

BeanFactory Spring之BeanFactory什么是BeanFactoryApplicationContext相对BeanFactory实现的功能性扩展1. MessageSource2. ResourcePatternResolver3. ApplicationEventPublisher4. EnvironmentCapable通用ApplicationContext实践实现BeanFactoryBeanFactory后处理器排序让谁…

跑MPS产生委外采购申请(成品)

问题:跑MPS产生委外采购申请(成品),更改BOM和跑MRP,但物料需求清单中无新增物料复合膜的需求。截图如下: 解决方法:更改委外采购申请的批准日期为BOM的生效日和重新展开bom。 重新展开后&#x…

“在中国,为中国” 英飞凌汽车业务正式发布中国本土化战略

3月28日,以“夯实电动化,推进智能化,实现高质量发展”为主题的2025中国电动汽车百人会论坛在北京举办。众多中外机构与行业上下游嘉宾就全球及中国汽车电动化的发展现状、面临的挑战与机遇,以及在技术创新、市场布局、供应链协同等…

优雅实现网页弹窗提示功能:JavaScript与CSS完美结合

在现代Web开发中,弹窗提示是提升用户体验的重要元素之一。本文将深入探讨如何实现一个优雅、可复用的弹窗提示系统,避免常见问题如重复触发、样式混乱等。 核心代码解析 // 控制弹窗是否可以显示的标志 let alertStatus true;// 显示提示信息 functio…

YOLOv11改进-双Backbone架构:利用双backbone提高yolo11目标检测的精度

一、引言:为什么我们需要双Backbone? 在目标检测任务中,YOLO系列模型因其高效的端到端检测能力而备受青睐。然而,传统YOLO模型大多采用单一Backbone结构,即利用一个卷积神经网络(CNN)作为特征提…

用 PyQt5 和 asyncio 打造接口并发测试 GUI 工具

接口并发测试是测试工程师日常工作中的重要一环,而一个直观的 GUI 工具能有效提升工作效率和体验。本篇文章将带你用 PyQt5 和 asyncio 从零实现一个美观且功能实用的接口并发测试工具。 我们将实现以下功能: 请求方法选择器 添加了一个下拉框 QComboBo…

理解npm的工作原理:优化你的项目依赖管理流程

目录 什么是npm npm核心功能 npm 常用指令及其作用 执行npm i 发生了什么? 1. 解析命令与参数 2. 检查依赖文件 3. 依赖版本解析与树构建 4. 缓存检查与包下载 5. 解压包到 node_modules 6. 更新 package-lock.json 7. 处理特殊依赖类型 8. 执行生命周期脚本 9. …

React Native 安卓端 android Image 播放gif webp 动态图

React Native 安卓端 android Image 播放gif webp 动态图 RN项目是0.78.2 React是19.0 基本介绍 Image 是 React Native 中用于显示各种类型图片的核心组件,支持显示网络图片、静态资源、本地图片以及 base64 编码的图片。在 Android 端,Image 组件还可…

实时数字人——DH_LIVE

前两天亲手搭建了实时对话数字人VideoChat,今天来搭建下DH_LIVE。 DH_LIVE一个实时数字人解决方案,从输入文字到数字人对口型说话用时2-3秒。 今天就来实际操作下dh_live的搭建过程。 首先贴上git地址:https://github.com/kleinlee/DH_liv…

AOSP CachedAppOptimizer 冻结方案

背景 Android 一直面临一个核心难题:如何优化进程对有限系统资源(如 CPU、电量)的使用,同时保证用户体验。 当进程进入后台后,它们虽不再贡献用户体验,却仍可能消耗资源。传统的杀后台方案虽然节省资源&a…

实体店的小程序转型之路:拥抱新零售的密码-中小企实战运营和营销工作室博客

实体店的小程序转型之路:拥抱新零售的密码-中小企实战运营和营销工作室博客 在当今数字化浪潮的冲击下,实体店面临着前所未有的挑战,但小程序的出现为实体店转型新零售带来了新的曙光。先来看一组惊人的数据,据相关统计&#xff…

Java求职面试:从Spring Boot到微服务的全面考核

Java求职面试实录:从Spring Boot到微服务的全面考核 第一轮:基础技术的考察 场景: 赵大宝走进了一家互联网大厂的面试间,面试官严肃地看着他。 面试官: 赵大宝,你好。我们先从简单的开始。请你解释一下J…

记录一个坑关于STM32 ARM Compiler Version

在用 Keil 进行 STM32 开发的时候,一开始下载,下载的 ARM 编译器是 Version6,他就不兼容老的代码,就很抽象。 所以必须要更换编译器。 可以去官网下载编译器 Downloads - Arm Developer ,也可以自己找资源哈&#xff…

PCIe体系结构学习入门——PCI总线概述(二)PCI总线的桥和配置

这里写目录标题 序言存储器域和 PCI 总线域HOST 主桥PCI 桥和 PCI 设备配置空间PCI 桥PCI 设备配置空间PCI 总线的配置非透明 PCI 桥序言 接续前章内容,本章继续讲述 PCI 总线概述的第二部分——PCI 总线的桥和配置。 如果需要进一步了解前一章节内容,可以访问:PCIe体系结构…

浔川代码编辑器v2.0(测试版)更新公告

浔川代码编辑器v2.0(测试版)更新公告 发布日期:** 2023年4月30日 我们很高兴地宣布浔川代码编辑器v2.0测试版即将上线!本次更新带来了多项功能改进和问题修复,旨在为用户提供更稳定、更强大的编程体验。 主要更新内容 1. **Bug修复与稳定性提…

微信小程序 tabbar底部导航栏

官方文档:https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html#tabBar 一、常规菜单格式 在app.json 文件中配置,其他关键点详见官方文档,后续更新不规则图标的写法

Spring 中@Autowired,@Resource,@Inject 注解实现原理

使用案例 前置条件: 现在有一个 Vehicle 接口,它有两个实现类 Bus 和 Car ,现在还有一个类 VehicleService 需要注入一个 Vehicle 类型的 Bean: public interface Vehicle {}Component public class Car implements Vehicle {}C…

【Rust结构体】Rust结构体详解:从基础到高级应用

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…

《LightLLM:开启大语言模型推理新时代》

《LightLLM:开启大语言模型推理新时代》 大语言模型推理的困境与挑战 在当今人工智能飞速发展的时代,大语言模型(LLMs)无疑是最为耀眼的明星技术之一。从 OpenAI 的 GPT 系列到谷歌的 BERT,再到国内如百度文心一言、阿里通义千问等,大语言模型以其强大的语言理解和生成能…