如何将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
相关产品推荐
相关产品推荐

