python爬取百度图片【最新升级版】
·
在日常学习和工作中,我们经常需要批量获取网络图片,比如做素材收集、数据集构建等。本文将以百度图片为例,手把手教你用 Python 实现图片批量爬取,从接口分析、反爬绕过到异常处理,完整覆盖爬虫开发的核心要点。
1. 核心依赖库
本次开发需要用到以下 Python 库,提前通过 pip 安装:
pip install requests beautifulsoup4
requests:发送 HTTP 请求,获取网页 / 接口数据json:解析百度图片返回的 JSON 格式数据(Python 内置)os:处理文件和目录(Python 内置)re:正则表达式,修复 JSON 格式问题(Python 内置)BeautifulSoup4:解析 HTML 页面(备用方案)traceback:定位代码异常(Python 内置)

百度图片提供了 JSON 格式的接口(返回图片链接等信息)
- 构造请求参数,模拟浏览器发送请求
- 解析接口返回的 JSON 数据,提取图片 URL
- 批量下载图片并按关键词分类保存
- 处理各类异常(接口解析失败、图片链接失效、网络超时等




2.完整代码实现
# 需要安装第三库:
# pip install requests
# pip install beautifulsoup4 用 BeautifulSoup 解析 HTML 中的图片链接,这样更稳定
import requests
import os
import json
import traceback #追踪信息
index = 1 #index初始值为1
def download(url, word):
global index # 声明使用全局变量index,确保函数内可以修改全局的序
if not url:
print("下载链接为空,跳过")
return
try: # 异常捕获:处理下载过程中可能出现的错误(如网络超时、链接失效等)
r = requests.get(url, timeout=15)
r.raise_for_status() # 检查响应状态码:如果不是200(成功),直接抛出异常
# 确保路径存在
save_dir = os.path.join('imgs', word)
if not os.path.exists(save_dir):
os.makedirs(save_dir, exist_ok=True) # 如果保存目录不存在,则创建(exist_ok=True:目录已存在时不报错)
name = os.path.join(save_dir, f'{index}.jpg')
with open(name, 'wb') as f: # wb写入二进制格式图片
f.write(r.content)
print(f"图片下载成功:{url},保存为:{name}")
index += 1
except Exception as e:
print(f"下载失败:{url},错误:{str(e)}")
if not os.path.exists("imgs"):
os.makedirs("imgs", exist_ok=True)
word = input("请输入下载关键字:")
num = int(input("请输入数量:"))
# 使用百度图片搜索API
for page in range(0, num):
# 计算pn参数,每页30张图片
pn = page * 30
# 构建请求URL
url = f"https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&ct=201326592&is=&fp=result&fr=&word={word}&queryWord={word}&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=&hd=&latest=©right=&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&expermode=&nojc=&isAsync=&pn={pn}&rn=30&gsm=1e&1623456789012="
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36',
'Referer': 'https://image.baidu.com/',
'Accept': 'text/plain, */*; q=0.01'
}
try:
print(f"\n请求第{page + 1}页数据...")
html = requests.get(url, headers=headers, timeout=15)
html.raise_for_status()
print(f"响应状态码:{html.status_code}")
# 预处理JSON数据,处理无效的转义字符
import re
# 修复无效的转义序列
raw_text = html.text
# 方法1:尝试使用更健壮的正则表达式修复无效转义
try:
# 替换无效的转义字符,只保留有效的转义序列
# 有效的转义序列:\", \\, \b, \f, \n, \r, \t, \uXXXX
raw_text = re.sub(r'(?<!\\)\\(?![\"\\/bfnrt]|u[0-9a-fA-F]{4})', r'\\\\', raw_text)
# 解析JSON数据
data = json.loads(raw_text)
except json.JSONDecodeError as e:
print(f"第一次JSON解析失败,尝试使用备用方法:{str(e)}")
# 方法2:尝试使用更简单的方法,移除所有无效的转义字符
try:
# 移除所有反斜杠,除了有效的转义序列
# 这是一个更激进的方法,可能会移除一些有用的转义序列,但可以解决大多数解析错误
raw_text = html.text
# 保留有效的转义序列
valid_escapes = ['\\"', '\\\\', '\\b', '\\f', '\\n', '\\r', '\\t']
# 临时替换有效的转义序列
for i, escape in enumerate(valid_escapes):
raw_text = raw_text.replace(escape, f'__ESCAPE_{i}__')
# 移除所有剩余的反斜杠
raw_text = raw_text.replace('\\', '')
# 恢复有效的转义序列
for i, escape in enumerate(valid_escapes):
raw_text = raw_text.replace(f'__ESCAPE_{i}__', escape)
# 解析JSON数据
data = json.loads(raw_text)
except json.JSONDecodeError as e2:
print(f"第二次JSON解析失败,尝试使用备用API:{str(e2)}")
# 方法3:使用备用的百度图片搜索API
# 构建备用API URL
backup_url = f"https://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=result&fr=&sf=1&fmq=1707724050277_R&pv=&ic=&nc=1&z=&hd=&latest=©right=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&sid=&word={word}"
print(f"使用备用API:{backup_url}")
# 发送备用请求
backup_response = requests.get(backup_url, headers=headers, timeout=15)
backup_response.raise_for_status()
# 从HTML中提取图片URL(简单方法)
from bs4 import BeautifulSoup
soup = BeautifulSoup(backup_response.text, 'html.parser')
# 查找所有图片标签
img_tags = soup.find_all('img')
print(f"从HTML中找到{len(img_tags)}个图片标签")
# 创建模拟的data结构
data = {'data': []}
for i, img in enumerate(img_tags[:10]): # 只取前10张图片
img_url = img.get('src') or img.get('data-src')
if img_url and img_url.startswith('http'):
data['data'].append({'thumbURL': img_url})
print(f"创建了{len(data['data'])}个模拟图片项")
# 检查是否有data字段
if 'data' in data:
image_data = data['data']
print(f"获取到{len(image_data)}个图片项")
# 遍历图片数据
for i, item in enumerate(image_data):
if isinstance(item, dict): # 检查当前项是否为字典类型(避免非字典数据导致报错)
# 尝试获取图片URL的多种可能字段
img_url = None
# 尝试所有可能的图片URL字段名
url_fields = ['objurl', 'thumburl', 'thumbURL', 'objURL', 'middleURL', 'middleurl', 'hoverURL',
'hoverurl', 'url']
for field in url_fields:
if field in item:
img_url = item[field]
print(f"从{field}字段找到URL:{img_url}")
break
if img_url:
download(img_url, word)
else:
print(f"第{i + 1}个图片:未找到URL")
else:
print(f"第{i + 1}个项:非字典类型,跳过")
else:
print("响应中没有data字段")
except Exception as e:
print(f"请求失败:{str(e)}")
traceback.print_exc() #追踪异常信息
3.核心知识点解析
①反爬绕过技巧
百度会识别非浏览器的请求,我们通过headers模拟浏览器:
User-Agent:标识浏览器类型和版本Referer:告诉服务器请求来自百度图片主页,模拟正常跳转- 超时设置:
timeout=15避免请求卡死
②JSON 解析容错处理
百度返回的 JSON 数据可能包含无效转义字符,导致解析失败,这里做了三层容错:
- 正则修复无效转义(保留有效转义序列)
- 激进移除无效反斜杠(备用方案)
- 降级到 HTML 解析(最终兜底)
③图片 URL 字段兼容
百度图片接口返回的图片链接字段不固定,我们遍历所有可能的字段名(如thumbURL、objURL、middleURL),确保能找到有效链接。
④异常处理
代码中覆盖了以下异常场景:
- 网络超时 / 请求失败(
requests.get超时 +raise_for_status) - 图片链接失效(下载函数的异常捕获)
- JSON 解析失败(三层降级方案)
- 目录创建失败(
os.makedirs的exist_ok=True)
运行代码
- 按照提示输入:
- 下载关键字(如 “树叶”“花朵”)
- 下载页数(每页 30 张图片)
- 下载的图片会保存在
imgs/关键词/目录下,按序号命名。

- 爬取频率:不要过于频繁请求(建议每页间隔 1-2 秒),避免 IP 被封禁
- 合规性:仅用于学习和个人非商用场景,遵守网站 robots 协议
- 扩展优化:可添加以下功能:
- 图片格式过滤(只下载 jpg/png)
- 断点续传(记录已下载序号)
- 多线程下载(提升效率)
- 代理 IP 池(避免 IP 封禁)
你可以基于此代码扩展更多功能,比如添加进度条、支持多关键词批量爬取、图片去重等,进一步提升爬虫的实用性。
更多推荐




所有评论(0)