Python图片爬取案例怎么编写?

wen python案例 2

Python图片爬取案例:从零到一的完整编写指南

目录导读

  1. 图片爬取的核心原理与法律边界
  2. 环境搭建与必备库安装
  3. 基础案例:单页图片批量下载
  4. 进阶案例:多线程加速与反爬规避
  5. 常见报错与调试技巧
  6. 问答环节:开发者最常遇到的5个问题

图片爬取的核心原理与法律边界

什么是图片爬取?
图片爬取是指通过自动化程序(通常用Python编写)从网页中获取图片资源,并将其保存到本地设备的过程,其本质是模拟浏览器向服务器发送HTTP请求,解析响应内容中的图片链接,然后下载图片文件。

关键法律提醒
根据《网络安全法》与《信息网络传播权保护条例》,爬取图片需注意:

  • 仅爬取公开、无版权限制的图片(如免费图库、公开作品)
  • 尊重网站的robots.txt协议
  • 控制请求频率,避免对服务器造成压力
  • 不得用于商业盈利或侵犯他人肖像权

推荐合法目标网站:Unsplash、Pexels、Pixabay等免版权图库。


环境搭建与必备库安装

基础环境要求

  • Python 3.8+(推荐3.10及以上版本)
  • 代码编辑器(VSCode / PyCharm / Sublime)

核心依赖库自动安装

pip install requests beautifulsoup4 lxml pillow
  • requests:发送HTTP请求获取网页内容
  • beautifulsoup4:解析HTML/XML文档,提取图片链接
  • lxml:高效的HTML解析器(解析速度比默认解析器快5倍)
  • Pillow:验证下载的图片是否损坏

可选增强库

pip install aiohttp fake-useragent retrying
  • aiohttp:异步爬取,速度提升3-10倍
  • fake-useragent:随机生成User-Agent,规避反爬检测
  • retrying:自动重试失败的请求

基础案例:单页图片批量下载

目标网站:Unsplash搜索页(公开API)
实现功能:下载首页所有预览图

完整代码

import requests
from bs4 import BeautifulSoup
import os
from urllib.parse import urljoin
# 配置参数
url = "https://unsplash.com/s/photos/nature"
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}
save_dir = "images/unsplash"
os.makedirs(save_dir, exist_ok=True)
# 1. 获取网页内容
response = requests.get(url, headers=headers, timeout=10)
response.encoding = "utf-8"
# 2. 解析HTML提取图片链接
soup = BeautifulSoup(response.text, "lxml")
img_tags = soup.find_all("img", {"src": True})
for idx, img in enumerate(img_tags):
    img_url = img.get("src")
    # 处理相对路径
    if not img_url.startswith("http"):
        img_url = urljoin(url, img_url)
    # 3. 下载图片(仅jpg/png)
    if img_url.endswith((".jpg", ".png", ".jpeg")):
        try:
            img_data = requests.get(img_url, headers=headers, timeout=5).content
            filename = f"{save_dir}/img_{idx}.jpg"
            with open(filename, "wb") as f:
                f.write(img_data)
            print(f"✅ 已下载: {filename}")
        except Exception as e:
            print(f"❌ 下载失败: {img_url},错误: {e}")

运行效果:约10秒内可下载20-30张预览图,文件保存在images/unsplash文件夹内。


进阶案例:多线程加速与反爬规避

痛点:单线程爬取100张图片需30秒,多线程可缩短至5秒。
解决方案:使用concurrent.futures线程池 + 随机请求头。

代码优化

import requests
from concurrent.futures import ThreadPoolExecutor, as_completed
from fake_useragent import UserAgent
import time
# 生成随机User-Agent
ua = UserAgent()
def download_single_image(img_url, idx, save_dir):
    """单个图片下载函数"""
    try:
        headers = {"User-Agent": ua.random}
        img_data = requests.get(img_url, headers=headers, timeout=8).content
        filename = f"{save_dir}/img_{idx:04d}.jpg"
        with open(filename, "wb") as f:
            f.write(img_data)
        return f"✅ 成功: {filename}"
    except Exception as e:
        return f"❌ 失败: {img_url},错误: {e}"
# 批量下载(多线程)
def batch_download(img_urls, save_dir, max_workers=10):
    start = time.time()
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        futures = {
            executor.submit(download_single_image, url, idx, save_dir): idx
            for idx, url in enumerate(img_urls)
        }
        for future in as_completed(futures):
            print(future.result())
    print(f"⏱️ 耗时: {time.time() - start:.2f}秒")
# 准备图片链接列表(示例)
all_img_urls = [
    "https://images.unsplash.com/photo-1",
    "https://images.unsplash.com/photo-2",
    # ... 可添加100个链接
]
batch_download(all_img_urls, "images/multi_thread")

反爬增强技巧

  • 每次请求更换User-Agent(如上代码)
  • 添加Referer头部模拟从主站跳转
  • 每次请求后随机休眠0.5-1秒
  • 使用代理IP池(付费或免费代理)

常见报错与调试技巧

错误类型 典型错误信息 解决策略
SSL证书 SSLError: CERTIFICATE_VERIFY_FAILED 添加verify=False参数,或升级certifi
403禁止 HTTP 403 Forbidden 添加有效User-AgentCookie
连接超时 TimeoutError 增加timeout值至10-15秒,或使用重试机制
图片损坏 IOError 下载后使用Pillow验证:Image.open(filename).verify()
动态加载 只能爬取到js文件 改用selenium或分析XHR请求真实接口

调试口诀
“先看状态码,再查Headers;动态内容用Selenium,静态解析BeautifulSoup;反爬层叠不放弃,重试休眠最管用。”


问答环节:开发者最常遇到的5个问题

Q1:为什么爬取的图片是空白的或损坏的?
A:最常见的原因是URL指向的是“缩略图”而非原始图片,解决方案:查看网页源代码,查找data-originalsrcsetdata-src属性,这些通常指向高清原图。

Q2:如何处理懒加载(Lazy Load)的图片?
A:懒加载的图片src属性通常为placeholder,真实链接存储在data-srcdata-original中,修改提取代码:

img_url = img.get("data-src") or img.get("data-original") or img.get("src")

Q3:爬取速度很慢,如何优化?
A:三种方案:

  1. 使用concurrent.futures多线程(提升3-5倍)
  2. 改用异步库aiohttp(提升10倍)
  3. 下载前先用HEAD请求检查图片是否存在,避免无效下载

Q4:如何绕过Cloudflare或CAPTCHA验证?
A:Cloudflare等CDN通常需要渲染JavaScript,推荐方案:

  • 使用cloudscraper库(模拟浏览器指纹)
  • splash无头浏览器实例
  • 或购买付费代理API服务

Q5:爬取的图片太大,导致内存溢出怎么解决?
A:使用流式下载(chunk),避免一次性加载全部内容:

response = requests.get(img_url, stream=True)
with open(filename, "wb") as f:
    for chunk in response.iter_content(chunk_size=8192):
        f.write(chunk)

总结与扩展建议

通过本文的案例,你已经掌握:

  • 使用requests+BeautifulSoup构建基础爬虫
  • 用多线程提升爬取效率
  • 规避常见反爬手段

下一站学习方向

  1. 使用scrapy框架构建分布式爬虫
  2. 配合opencv自动分类下载的图片
  3. 构建图片去重系统(基于MD5或感知哈希)

代码只是工具,合理合法使用才是技术人的担当,如有任何问题,欢迎在技术社区与我交流。

标签: Python案例

抱歉,评论功能暂时关闭!