Python 爬虫实战:批量下载百度图片
1. 前言
网络爬虫(Web Crawler)是自动化抓取网页信息的程序,广泛应用于数据采集、监控和分析。本教程将深入讲解如何使用 Python 编写一个高效的爬虫程序,实现批量下载百度搜索结果中的图片。通过本项目,读者可以掌握 HTTP 请求、JSON 数据解析、文件 IO 操作以及基本的反爬策略。
2. 环境准备
在开始之前,请确保你的开发环境已安装 Python 3.x 版本,并安装了 requests 库用于发送网络请求。
pip install requests
如果未安装,上述命令会自动从 PyPI 下载并安装依赖包。
3. 原理分析
3.1 页面结构分析
打开百度图片搜索页面,输入关键词(如'玫瑰'),按回车键查看结果。观察发现,初始加载的图片数量有限,随着鼠标滚动加载更多图片。这表明页面采用了异步加载技术(AJAX),而非一次性渲染所有 HTML。
3.2 接口抓包
- 打开浏览器开发者工具(F12),切换到'网络(Network)'标签页。
- 勾选'XHR'或'Fetch/XHR'过滤器,以便筛选 AJAX 请求。
- 向下滚动页面,观察新产生的请求。
- 点击其中一个请求,查看其'预览(Preview)'或'响应(Response)'。
可以发现返回的数据格式为 JSON,其中包含了图片的缩略图链接和原始图片链接。关键参数包括:
queryWord: 搜索关键词(URL 编码后)。pn: 分页偏移量(每页 30 张)。例如pn=0,pn=30,pn=60。rn: 返回数量(通常为 30)。tn: 固定参数,标识请求类型。
3.3 URL 构造
通过分析多个请求,我们可以发现 URL 的结构具有规律性。核心 API 地址通常为 https://image.baidu.com/search/acjson。我们需要动态替换其中的关键词和分页参数来构建完整的请求 URL。
4. 代码实现
基于上述分析,我们设计一个面向对象的结构来管理爬虫逻辑。主要包含初始化、目录创建、链接获取、图片保存和主运行流程。
# -*- coding: utf-8 -*-
import requests
import json
from urllib import parse
import os
import time
import random
class BaiduImageSpider(object):
def __init__(self):
# 请求到的 json 文件数量(一个 json 文件包含 30 个图像文件)
self.json_count = 0
.url_template = (
)
.directory_template =
.header = {
: (
)
}
():
base_dir = .directory_template.(name)
os.path.exists(base_dir):
os.makedirs(base_dir)
base_dir
():
list_image_link = []
:
strhtml = requests.get(url, headers=.header, timeout=)
strhtml.encoding =
jsonInfo = json.loads(strhtml.text)
jsonInfo (jsonInfo[]) > :
item jsonInfo[]:
item:
list_image_link.append(item[])
Exception e:
()
list_image_link
():
:
res = requests.get(img_link, headers=.header, timeout=)
res.status_code == :
(filename, ) f:
f.write(res.content)
:
()
Exception e:
()
():
searchName = ()
searchName:
()
searchName_parse = parse.quote(searchName)
target_dir = .create_directory(searchName)
pic_number =
total_images =
()
index (.json_count):
pn = index *
request_url = .url_template.(
searchName_parse,
searchName_parse,
(pn)
)
list_image_link = .get_image_link(request_url)
link list_image_link:
pic_number +=
file_name =
.save_image(link, file_name):
total_images +=
time.sleep(random.uniform(, ))
()
__name__ == :
spider = BaiduImageSpider()
spider.json_count =
spider.run()


