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

如何将Scrapy爬取结果正确存入MySQL数据库?

如何将Scrapy爬取的数据存入MySQL数据库

我来帮你解决这个问题,你当前的代码里数据库操作和爬虫逻辑完全脱节了——你只在脚本末尾插入了一组固定测试值,根本没把爬取到的实际数据关联到数据库操作里。Scrapy设计了Item Pipeline来专门处理数据的清洗、验证和存储,这是最规范也最可靠的实现方式,下面一步步教你修改:

步骤1:定义Scrapy Item(可选但推荐)

先在items.py里定义结构化的Item类,让爬取的数据更规范:

import scrapy

class BanggoodItem(scrapy.Item):
    producttitle = scrapy.Field()
    productlink = scrapy.Field()
    productprice = scrapy.Field()

步骤2:编写MySQL存储Pipeline

在pipelines.py里实现数据库存储的Pipeline类,这里我们会在爬虫启动时打开数据库连接,关闭时关闭连接,每处理一个Item就执行一次插入:

import pymysql.cursors

class BanggoodMySQLPipeline:
    def open_spider(self, spider):
        # 爬虫启动时初始化数据库连接
        self.connection = pymysql.connect(
            host='localhost',
            user='root',
            password='Kradz579032!!',
            db='db',
            charset='utf8mb4',
            cursorclass=pymysql.cursors.DictCursor
        )
        self.cursor = self.connection.cursor()

    def close_spider(self, spider):
        # 爬虫关闭时关闭数据库连接
        self.cursor.close()
        self.connection.close()

    def process_item(self, item, spider):
        # 插入爬取到的Item数据到数据库
        try:
            sql = """
                INSERT INTO `banggood` (`producttitle`, `productlink`, `productprice`)
                VALUES (%s, %s, %s)
            """
            self.cursor.execute(sql, (
                item['producttitle'],
                item['productlink'],
                item['productprice']
            ))
            self.connection.commit()
        except Exception as e:
            spider.logger.error(f"插入数据失败: {e}")
            self.connection.rollback()
        return item

步骤3:在Settings中启用Pipeline

打开settings.py,找到ITEM_PIPELINES配置项,取消注释并添加我们的Pipeline:

ITEM_PIPELINES = {
    'your_project_name.pipelines.BanggoodMySQLPipeline': 300,
}

注意把your_project_name替换成你实际的Scrapy项目名称,数字300是优先级,数值越小越先执行。

步骤4:修改爬虫代码,返回Item对象

现在修改你的爬虫代码,让它返回我们定义的BanggoodItem(或者也可以返回字典,但用Item更规范),同时修正CSS选择器的问题——你原来的response.css('a.middle_product_text_170717::text').extract()会返回所有匹配的文本列表,而我们需要的是每个商品对应的单个值,应该用extract_first()或者.get():

import scrapy
from your_project_name.items import BanggoodItem  # 替换成你的项目名

class QuotesSpider(scrapy.Spider):
    name = "quotes"
    start_urls = [
        'https://www.banggood.com/Wholesale-RC-Helicopter-c-264.html',
        'https://www.banggood.com/Wholesale-RC-Quadcopters-c-1848.html',
    ]

    def parse(self, response):
        for quote in response.css('.good_box_min'):
            item = BanggoodItem()
            # 修正选择器,获取单个商品的对应值
            item['producttitle'] = quote.css('a.middle_product_text_170717::text').get().strip()
            item['productlink'] = response.urljoin(quote.css('a.middle_product_text_170717::attr(href)').get())
            item['productprice'] = quote.css('span.price.wh_cn::text').get().strip()
            yield item

        next_page = response.css('a#listNextPage::attr(href)').get()
        if next_page is not None:
            yield response.follow(next_page, callback=self.parse)

关键说明

  • 为什么用Pipeline?Scrapy的Pipeline机制可以让你把爬取和存储逻辑分离,代码更清晰,还能方便添加其他处理步骤(比如数据去重、清洗)。
  • 数据库连接的最佳实践:在open_spider和close_spider里处理连接的打开和关闭,避免每次处理Item都创建新连接,提升效率。
  • 选择器修正:你原来用extract()会返回列表,而每个商品对应单个值,所以用get()(等价于extract_first())更合适,还要用strip()去除多余的空格换行。

现在运行你的爬虫:scrapy crawl quotes,爬取到的每个商品数据就会自动存入MySQL数据库了。

内容的提问来源于stack exchange,提问作者Reezal AQ

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:32:55