You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Scrapy管道将爬取的图片直接保存到MySQL数据库

Scrapy 图片直接存入MySQL数据库解决方案

问题根源

默认scrapy.pipelines.images.ImagesPipeline处理后,item['['images']仅存储图片本地路径、校验码、URL等元数据,不包含图片二进制内容,因此无法直接用于数据库存储。

修改步骤

1. 新增自定义图片管道(替换默认管道)

在pipelines.py中新增继承自ImagesPipeline的自定义类,直接抓取图片二进制内容,无需写入本地磁盘:

import scrapy
from scrapy.pipelines.images import ImagesPipeline
from scrapy.exceptions import DropItem
import io
from PIL import Image
import mysql.connector
from decouple import config

class CustomImagesPipeline(ImagesPipeline):
    def get_images(self, response, request, info, *, item=None):
        # 直接获取响应中的图片二进制内容
        image_bytes = response.body
        # 校验图片有效性
        try:
            Image.open(io.BytesIO(image_bytes))
        except Exception:
            raise DropItem(f"无效图片链接:{request.url}")
        # 绑定图片URL和二进制内容存入item
        if not item.get("image_bytes_list"):
            item["image_bytes_list"] = []
        item["image_bytes_list"].append({
            "url": request.url,
            "content": image_bytes
        })
        # 跳过默认的本地文件写入逻辑
        return []

    def item_completed(self, results, item, info):
        # 校验所有图片下载成功
        for ok, err in results:
            if not ok:
                raise DropItem(f"图片下载失败:{err.value}")
        return item

2. 修改items.py新增二进制存储字段

import scrapy

class MyItem(scrapy.Item):
    image_urls = scrapy.Field()
    image_bytes_list = scrapy.Field() # 存储图片URL和对应二进制

3. 修改settings.py调整管道配置

替换默认图片管道,调整执行优先级,无需配置本地存储路径IMAGES_STORE:

ITEM_PIPELINES = {
    # 替换为你的实际项目名,自定义图片管道先执行
    "你的项目名.pipelines.CustomImagesPipeline": 1,
    # MySQL存储管道后执行
    "你的项目名.pipelines.SavetoMySQL": 300
}

4. 修正SavetoMySQL存储逻辑

修复原代码中的表名不统一、缺少事务提交、未指定操作数据库的问题:

class SavetoMySQL:
    def __init__(self):
        self.user = config("DB_USER")
        self.password = config("DB_PASSWORD")
        self.host = config("DB_HOST")
        self.port = config("DB_PORT")
        self.db_name = config("DB_NAME") # 新增配置项,填你的数据库名称
    
    def connect_database(self):
        self.conn = mysql.connector.connect(
            host=self.host,
            user=self.user,
            password=self.password,
            port=self.port,
            database=self.db_name # 指定操作的数据库
        )
    def create_table(self):
        self.curr = self.conn.cursor()
        self.curr.execute("""CREATE TABLE IF NOT EXISTS myitem_db(
                                image_urls VARCHAR(300),
                                images LONGBLOB);
                            """)

    def store_db(self, item):
        # 表名和建表语句保持一致
        insert_stmt = "INSERT INTO myitem_db(image_urls, images) VALUES (%s,%s)"
        for img_info in item["image_bytes_list"]:
            data = (img_info["url"], img_info["content"])
            self.curr.execute(insert_stmt, data)
        # 提交事务,否则数据不会写入数据库
        self.conn.commit()

    def open_spider(self, spider):
        self.connect_database()
        self.create_table()

    def process_item(self, item, spider):
        self.store_db(item)
        return item
    
    def close_spider(self, spider):
        self.curr.close()
        self.conn.close()

依赖安装

需要安装Pillow库用于图片有效性校验:

pip install pillow

内容的提问来源于stack exchange,提问作者TAN YONG SHENG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 13:15:02