手把手教你写一个图片爬虫

简介: 本文介绍了一个实用的百度图片爬虫工具,仅需百余行 Python 代码即可实现自动搜索与下载图片功能,适用于需要批量获取图片素材的场景。爬虫包含请求处理、JSON 解析、文件操作等关键技术,并详细解析了其设计与实现原理,适合学习与扩展。

最近想收集一些特定主题的图片素材,手动一张张下载实在太费时间了。作为一个懒人程序员,我决定写个爬虫来自动完成这个任务。今天就跟大家分享这个实用的百度图片爬虫,它能自动搜索并下载你想要的任何图片。

这个爬虫虽然只有100多行代码,但包含了请求处理、JSON解析、文件操作等实用技巧。我会详细解释每个部分的实现思路,让你不仅能使用这个爬虫,还能真正理解它的工作原理。

爬虫整体设计

我们先来看看这个爬虫的总体结构:

代码语言:python

代码运行次数:0

运行

AI代码解释

class BaiduImageSpider(object):
    def __init__(self):
        # 初始化代码
    
    def create_directory(self, name):
        # 创建保存图片的文件夹
    
    def get_image_link(self, url):
        # 获取图片链接
    
    def save_image(self, img_link, filename):
        # 下载并保存图片
    
    def run(self):
        # 主运行逻辑

这个类包含了爬虫的所有功能,结构清晰,每个方法负责一个具体的任务。接下来我会详细讲解每个部分的实现。

初始化设置

代码语言:python

代码运行次数:0

运行

AI代码解释

def __init__(self):
    self.json_count = 0
    self.url = 'https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&queryWord={}&word={}&pn={}&rn=30'
    self.directory = r"C:\价值一个亿\python-mini-projects\projects\baidutupian\{}"
    self.header = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36',
        'Accept-Language': 'en-US,en;q=0.5',
        'Referer': 'https://image.baidu.com'
    }
    self.image_counter = 0  # 新增全局图片计数器

初始化方法中,我们设置了几个重要的变量:

  1. json_count:控制要下载多少组图片(每组30张)
  2. url:百度图片的API接口地址,使用格式化字符串方便后续替换关键词
  3. directory:图片保存路径,使用{}作为占位符方便后续替换
  4. header:请求头,模拟浏览器访问,避免被反爬
  5. image_counter:图片计数器,用于生成唯一的文件名

创建保存目录

代码语言:python

代码运行次数:0

运行

AI代码解释

def create_directory(self, name):
    self.directory = self.directory.format(name)
    os.makedirs(self.directory, exist_ok=True)
    self.directory += r'\{}'

这个方法负责创建保存图片的文件夹:

  1. 使用format方法将搜索关键词插入到路径中
  2. os.makedirs创建目录,exist_ok=True表示如果目录已存在也不报错
  3. 最后在路径后添加\{},方便后续格式化文件名

获取图片链接

代码语言:python

代码运行次数:0

运行

AI代码解释

def get_image_link(self, url):
    try:
        response = requests.get(
            url,
            headers=self.header,
            proxies={"http": None, "https": None},
            timeout=10
        )
        response.raise_for_status()
        return [item['thumbURL'] for item in response.json().get('data', []) if 'thumbURL' in item]
    except Exception as e:
        print(f"获取图片链接失败: {e}")
        return []

这是爬虫的核心方法之一,负责从百度API获取图片链接:

  1. 使用requests.get发送HTTP请求
  2. 设置了请求头和代理(这里禁用了代理)
  3. 添加了10秒超时设置
  4. raise_for_status()会在请求失败时抛出异常
  5. 使用列表推导式从返回的JSON中提取所有thumbURL字段
  6. 添加了异常处理,失败时打印错误信息并返回空列表

下载并保存图片

代码语言:python

代码运行次数:0

运行

AI代码解释

def save_image(self, img_link, filename):
    try:
        res = requests.get(
            img_link,
            headers=self.header,
            proxies={"http": None, "https": None},
            timeout=10
        )
        res.raise_for_status()
        
        with open(filename, "wb") as f:
            f.write(res.content)
            print(f"成功保存: {filename}")
    except Exception as e:
        print(f"下载图片失败: {e}")

这个方法负责下载并保存图片:

  1. 同样使用requests.get获取图片内容
  2. 以二进制写入模式(wb)打开文件
  3. 直接将响应内容写入文件
  4. 添加了异常处理,下载失败时打印错误信息

主运行逻辑

代码语言:python

代码运行次数:0

运行

AI代码解释

def run(self):
    searchName = input("查询内容:")
    searchName_parse = parse.quote(searchName)
    self.create_directory(searchName)
    self.image_counter = 0  # 重置计数器
    for index in range(self.json_count):
        pn = index * 30
        request_url = self.url.format(searchName_parse, searchName_parse, str(pn))
        links = self.get_image_link(request_url)
        for link in links:
            filename = os.path.join(self.directory.format(f"{self.image_counter}.jpg"))  # 使用全局计数器
            self.save_image(link, filename)
            self.image_counter += 1  # 计数器递增
            time.sleep(1)
    print(f"{searchName}----图像下载完成--------->")

这是爬虫的主控制流程:

  1. 获取用户输入的搜索关键词
  2. 对关键词进行URL编码
  3. 创建保存目录
  4. 重置图片计数器
  5. 循环获取多组图片(每组30张)
  6. 构建请求URL,pn参数控制分页
  7. 获取图片链接列表
  8. 逐个下载图片,文件名使用递增的数字
  9. 每次下载后暂停1秒,避免请求过于频繁
  10. 完成后打印提示信息

扩展思路

这个基础爬虫还可以进一步扩展:

  1. 支持更多搜索引擎:除了百度,还可以添加谷歌、必应等图片搜索的支持
  2. 图片筛选:根据大小、格式、颜色等条件筛选图片
  3. 去重功能:使用哈希值检查避免下载重复图片
  4. 断点续传:记录已下载的图片,程序中断后可以从中断处继续
  5. GUI界面:使用PyQt或Tkinter添加图形界面,更方便非技术人员使用

完整代码

代码语言:python

代码运行次数:0

运行

AI代码解释

import requests
import json
from urllib import parse
import os
import time
class BaiduImageSpider(object):
    def __init__(self):
        self.json_count = 0
        self.url = 'https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&queryWord={}&word={}&pn={}&rn=30'
        self.directory = r"C:\价值一个亿\python-mini-projects\projects\baidutupian\{}"
        self.header = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36',
            'Accept-Language': 'en-US,en;q=0.5',
            'Referer': 'https://image.baidu.com'
        }
        self.image_counter = 0  # 新增全局图片计数器
    def create_directory(self, name):
        self.directory = self.directory.format(name)
        os.makedirs(self.directory, exist_ok=True)
        self.directory += r'\{}'
    def get_image_link(self, url):
        try:
            response = requests.get(
                url,
                headers=self.header,
                proxies={"http": None, "https": None},
                timeout=10
            )
            response.raise_for_status()
            return [item['thumbURL'] for item in response.json().get('data', []) if 'thumbURL' in item]
        except Exception as e:
            print(f"获取图片链接失败: {e}")
            return []
    def save_image(self, img_link, filename):
        try:
            res = requests.get(
                img_link,
                headers=self.header,
                proxies={"http": None, "https": None},
                timeout=10
            )
            res.raise_for_status()
            
            with open(filename, "wb") as f:
                f.write(res.content)
                print(f"成功保存: {filename}")
        except Exception as e:
            print(f"下载图片失败: {e}")
    def run(self):
        searchName = input("查询内容:")
        searchName_parse = parse.quote(searchName)
        self.create_directory(searchName)
        self.image_counter = 0  # 重置计数器
        for index in range(self.json_count):
            pn = index * 30
            request_url = self.url.format(searchName_parse, searchName_parse, str(pn))
            links = self.get_image_link(request_url)
            for link in links:
                filename = os.path.join(self.directory.format(f"{self.image_counter}.jpg"))  # 使用全局计数器
                self.save_image(link, filename)
                self.image_counter += 1  # 计数器递增
                time.sleep(1)
        print(f"{searchName}----图像下载完成--------->")
if __name__ == '__main__':
    spider = BaiduImageSpider()
    spider.json_count = 10  # 下载10组图片
    spider.run()

使用说明

  1. 安装依赖:pip install requests
  2. 运行方式:
  • 直接运行:tupian.py
  • 或者导入使用:

代码语言:python

代码运行次数:0

运行

AI代码解释

if __name__ == '__main__':
    spider = BaiduImageSpider()
    spider.json_count = 10  # 下载10组图片
    spider.run()
  1. 创建爬虫实例
  2. 设置json_count决定下载多少组图片(每组30张)
  3. 调用run()方法开始爬取

运行后会提示输入搜索关键词,然后就会自动下载图片到指定目录。

高级技巧

  1. 代理设置:如果需要使用代理,可以修改请求方法:

代码语言:python

代码运行次数:0

运行

AI代码解释

proxies = {
    'http': 'http://your.proxy:port',
    'https': 'http://your.proxy:port'
}
response = requests.get(url, headers=self.header, proxies=proxies)
  1. 多线程下载:可以使用concurrent.futures实现:

代码语言:python

代码运行次数:0

运行

AI代码解释

from concurrent.futures import ThreadPoolExecutor
with ThreadPoolExecutor(max_workers=5) as executor:
    executor.map(self.save_image, links)
  1. 断点续传:记录已下载的URL,程序重启后跳过已下载的图片。

注意事项

  1. 请遵守百度的robots.txt协议,合理控制请求频率
  2. 不要用于商业用途,尊重图片版权
  3. 建议设置合理的json_count值,避免请求过多被封IP
  4. 下载失败时,程序会自动重试,但大量失败可能是触发了反爬机制

这个改进版的百度图片爬虫具有更好的稳定性、更详细的日志输出和更友好的使用体验。你可以根据自己的需求进一步扩展功能,比如添加图片去重、自动分类等功能。

相关文章
|
人工智能 缓存 vr&ar
big.LITTLE&DynamIQ
big.LITTLE&DynamIQ
690 0
|
8月前
|
XML 算法 数据格式
当Word文档里的图片成了“拦路虎”:用Python批量处理图片的实战指南
本文分享用Python批量处理Word文档图片的实战方案:利用python-docx提取图片、Pillow统一调整尺寸与格式,并自动插入新报告文档。附完整代码与常见问题(如浮动图、.doc格式)解决方案,助你3分钟完成原本一整天的手工活。
918 1
|
XML 机器学习/深度学习 数据格式
YOLOv8训练自己的数据集+常用传参说明
YOLOv8训练自己的数据集+常用传参说明
28061 3
|
8月前
|
机器学习/深度学习 监控 算法
驾驶员行为数据集(14000张高清标注)| YOLO训练实战 危险驾驶行为识别
本项目开源高质量驾驶员危险行为数据集,含14000张高清标注图像,覆盖饮食、玩手机、睡觉三类行为,严格按YOLO格式划分训练/验证/测试集,支持YOLOv5/v8/v11直接训练,兼顾精度与泛化性,助力DMS研发与智能座舱落地。
1619 12
|
5月前
|
缓存 人工智能 自然语言处理
阿里云Qwen3.7-Max全面评测:Agent智能体能力、计费方案与落地场景说明
2026年,AI行业正式迈入智能体(Agent)规模化落地的新阶段,能否支撑长周期自主任务、控制算力调用成本,成为企业与开发者选择大模型的两大核心标准。阿里云百炼平台重磅推出**Qwen3.7-Max**,作为通义千问系列面向智能体时代的旗舰大模型,该产品彻底突破传统对话模型的能力边界,主打长周期自主执行、全栈编程、办公自动化三大核心能力,同时搭配限时五折优惠与海量免费Token额度,大幅降低AI应用落地门槛。本文结合官方基准测试数据、功能特性、应用场景、调用方式、计费规则以及MCP集成方案,全方位解读Qwen3.7-Max,帮助个人开发者、初创团队、中大型企业全面了解这款旗舰模型
1236 1
|
11月前
|
人工智能 计算机视觉 测试技术
Meta SAM3开源
Meta发布并开源SAM 3,首个支持文本、点、框等多提示的统一图像视频分割模型,突破性实现开放词汇概念的全实例分割。基于Meta Perception Encoder与DETR架构,结合AI与人工协同数据引擎,构建超400万概念数据集,在SA-Co基准达人类水平75%-80%。支持大规模可提示分割与跟踪,推动视觉基础模型新进展。(239字)
|
网络协议 开发工具 git
解决 git 报错 “fatal: unable to access ‘https://github.com/.../.git‘: Recv failure Connection was rese
在使用 Git/Git小乌龟 进行代码管理的过程中,经常会遇到各种各样的问题,其中之一就是在执行 git clone 或 git pull 等操作时出现 “fatal: unable to access ‘https://github.com/…/.git’: Recv failure Connection was reset” 的报错。这个问题通常是由网络连接问题或代理设置不正确导致的。在我的个人使用经验中,我亲自尝试了四种方法,它们都能够有效地解决这个报错。个人比较推荐方法二。
10848 1
|
安全 网络安全 数据安全/隐私保护
解决SSH测试连接GitHub时出现“connection closed by remote host”的问题。
然后使用 `ssh -T git@ssh.github.com`来测试连接。
1395 0

热门文章

最新文章