在数据爬取、图像识别、内容聚合等项目中,常常需要从网络上采集图片素材,并将其保存到本地或数据库中。本文将详细介绍如何使用 Python 实现这一流程:包括发送 HTTP 请求获取网页内容、解析图片链接、下载图片,并最终将图片以二进制形式存储到数据库(以 SQLite 为例)。


一、准备工作

1. 安装依赖库

代码语言:javascript

AI代码解释

bash编辑pip install requests beautifulsoup4 pillow
  • requests:用于发送 HTTP 请求;
  • beautifulsoup4:用于解析 HTML 页面,提取图片链接;
  • Pillow(可选):用于验证或处理图片(如缩放、格式转换等)。

注意:如果目标网站有反爬机制(如验证码、User-Agent 检测等),可能还需使用 selenium 或设置请求头模拟浏览器行为。


二、基本流程概述

  1. 发送请求 获取目标网页 HTML 内容;
  2. 解析 HTML 提取所有 <img> 标签的 src 属性;
  3. 过滤有效图片链接(如 http/https 开头、常见图片格式);
  4. 下载图片 并读取为二进制数据;
  5. 连接数据库,创建表结构;
  6. 将图片二进制数据插入数据库

三、代码实现

1. 创建数据库表

我们使用 SQLite 存储图片(也可替换为 MySQL、PostgreSQL 等):

代码语言:javascript

AI代码解释

python编辑import sqlite3

def init_db():
    conn = sqlite3.connect('images.db')
    cursor = conn.cursor()
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS images (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            url TEXT NOT NULL,
            filename TEXT,
            data BLOB NOT NULL
        )
    ''')
    conn.commit()
    conn.close()
2. 下载并保存图片到数据库

代码语言:javascript

AI代码解释

python编辑import requests
import os
from urllib.parse import urljoin, urlparse

def download_image_to_db(session, img_url, base_url=None):
    try:
        # 处理相对链接
        if base_url and not img_url.startswith(('http://', 'https://')):
            img_url = urljoin(base_url, img_url)

        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
        }
        response = session.get(img_url, headers=headers, timeout=10)
        response.raise_for_status()

        # 简单判断是否为图片(通过 Content-Type 或扩展名)
        content_type = response.headers.get('content-type', '')
        if 'image' not in content_type:
            print(f"跳过非图片资源: {img_url}")
            return False

        # 获取文件名
        parsed = urlparse(img_url)
        filename = os.path.basename(parsed.path) or "unknown.jpg"

        # 保存到数据库
        conn = sqlite3.connect('images.db')
        cursor = conn.cursor()
        cursor.execute(
            "INSERT INTO images (url, filename, data) VALUES (?, ?, ?)",
            (img_url, filename, response.content)
        )
        conn.commit()
        conn.close()
        print(f"✅ 已保存: {filename}")
        return True

    except Exception as e:
        print(f"❌ 下载失败 {img_url}: {e}")
        return False
3. 从网页提取图片链接并批量下载

代码语言:javascript

AI代码解释

python编辑from bs4 import BeautifulSoup

def scrape_images_from_page(url):
    session = requests.Session()
    try:
        headers = {'User-Agent': 'Mozilla/5.0'}
        res = session.get(url, headers=headers)
        res.raise_for_status()
        soup = BeautifulSoup(res.text, 'html.parser')

        img_tags = soup.find_all('img')
        img_urls = [img.get('src') for img in img_tags if img.get('src')]

        print(f"共找到 {len(img_urls)} 个图片链接")
        for img_url in img_urls:
            download_image_to_db(session, img_url, base_url=url)

    except Exception as e:
        print(f"页面解析失败: {e}")
4. 主程序入口

代码语言:javascript

AI代码解释

python编辑if __name__ == "__main__":
    init_db()
    target_url = "https://www.jsonla.com/tupian/"  # 替换为目标网页
    scrape_images_from_page(target_url)

四、注意事项与优化建议

1. 合法性与道德
  • 请确保你有权采集目标网站的图片(遵守 robots.txt 和版权法规);
  • 避免高频请求,可添加 time.sleep() 控制频率;
  • 尊重网站服务器负载,建议使用 Session 复用连接。
2. 图片去重

可在数据库中对 url 字段加唯一索引,避免重复下载:

代码语言:javascript

AI代码解释

sql编辑CREATE UNIQUE INDEX IF NOT EXISTS idx_url ON images(url);
3. 大图处理

若图片过大,可先检查 Content-Length,或限制文件大小:

代码语言:javascript

AI代码解释

python编辑if int(response.headers.get('content-length', 0)) > 5 * 1024 * 1024:  # 5MB
    print("图片过大,跳过")
    return False
4. 替代方案:保存路径而非二进制

对于大量图片,直接存二进制到数据库可能导致性能下降。更常见的做法是:

  • 下载图片到本地文件夹(如 ./images/xxx.jpg);
  • 数据库存储文件路径和元信息。

五、总结

本文展示了如何使用 Python 从网页采集图片并保存到 SQLite 数据库的完整流程。核心在于:

  • 使用 requests + BeautifulSoup 解析页面;
  • 通过 BLOB 类型将图片二进制数据存入数据库;
  • 注意反爬策略、错误处理与资源合法性。

你可以根据实际需求扩展功能,例如支持多线程下载、对接云存储、自动打标签等。

📌 提示:生产环境中建议使用更健壮的数据库(如 PostgreSQL 的 bytea 类型)或对象存储(如 AWS S3 + 数据库存储 URL)。


希望这篇文章对你有所帮助!如有疑问,欢迎继续探讨。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐