标签:#Python爬虫 #Scrapy框架 #分页爬虫 #数据持久化 #爬虫项目实战
前言
上一篇我们从零入门了Scrapy框架,掌握了项目创建、目录结构、基础爬虫编写、Xpath数据解析、基础防爬配置,成功实现了单页面静态数据爬取。
但在真实爬虫项目中,单页爬取几乎没有实用价值。绝大多数网站的列表数据都会分页展示,想要批量采集完整数据,必须实现自动翻页爬取。
同时,仅把数据打印在控制台远远不够,爬虫最终目的是数据落地存储。
本篇承接前文,手把手实战Scrapy两大核心进阶能力:全自动分页爬取、工程化数据持久化。实现CSV本地文件、MySQL数据库双渠道自动存储,所有代码模块化、可直接运行、可无缝复用,彻底告别零散手写爬虫,进阶标准框架级爬虫开发!
一、前置环境依赖安装
本篇需要用到数据库连接库,终端执行国内镜像源一键安装,适配所有Python环境,解决下载超时、安装失败问题:
pip install scrapy pymysql -i https://pypi.tuna.tsinghua.edu.cn/simple/依赖说明
✅ scrapy:框架核心,实现爬虫调度、请求、解析全流程
✅ pymysql:连接MySQL数据库,实现数据入库持久化
✅ CSV存储为Scrapy原生自带功能,无需额外安装依赖
二、快速梳理Scrapy核心目录
延续上篇项目结构,本篇仅修改核心业务文件,新手无需新增多余目录:
spiders文件夹:编写分页爬虫核心逻辑
items.py:定义标准化爬取数据字段
pipelines.py:编写数据存储逻辑(CSV+MySQL)
settings.py:开启管道、配置防爬参数
三、标准化数据字段定义(items.py)
正规Scrapy项目不使用原生字典存数据,统一通过Item类规范字段,避免数据混乱、字段缺失,方便管道统一处理。直接替换items.py全部代码:
import scrapyclass ArticleItem(scrapy.Item):# 统一定义爬取字段title = scrapy.Field() # 文章标题link = scrapy.Field() # 文章详情链接publish_time = scrapy.Field() # 发布时间desc = scrapy.Field() # 内容摘要
四、核心实战:全自动分页爬虫编写(spiders/xxx.py)
Scrapy分页爬取是框架核心优势,无需手动写循环、无需管理页码,通过递归请求即可实现无限自动翻页,直到无下一页自动停止。
本次采用通用测试列表页逻辑,代码无报错、可直接自测运行,完整可运行爬虫代码:
import scrapyfrom my_spider.items import ArticleItemclass PageSpider(scrapy.Spider):# 爬虫名称,启动命令:scrapy crawl page_crawlname = "page_crawl"# 限制爬取域名,防止跨站allowed_domains = ["demo.scrapy.com"]# 起始列表页start_urls = ["https://demo.scrapy.com/list"]def parse(self, response):# 1、解析列表页所有文章article_list = response.xpath("//div[@class='list-item']")for item in article_list:data = ArticleItem()# xpath .// 代表当前节点下查找,不要漏写点data["title"] = item.xpath(".//h2/a/text()").get(default="")data["link"] = item.xpath(".//h2/a/@href").get(default="")data["publish_time"] = item.xpath(".//span[@class='time']/text()").get(default="")data["desc"] = item.xpath(".//p[@class='desc']/text()").get(default="")yield data# 2、翻页逻辑,获取下一页next_href = response.xpath("//a[contains(text(),'下一页')]/@href").get()if next_href:# urljoin自动处理相对路径/绝对路径next_url = response.urljoin(next_href)yield scrapy.Request(url=next_url, callback=self.parse)
核心知识点解析
1、response.urljoin():自动补全相对路径,彻底规避404请求错误,新手必备;
2、递归回调parse函数,无需手动循环,框架自动调度分页任务;
3、get(default="") 兜底空值,页面元素缺失不影响整体爬虫运行。
五、数据持久化①:一键CSV导出(零代码配置)
Scrapy原生支持文件导出,无需编写任何存储代码,终端一行命令自动将爬取数据保存为CSV文件,可直接用Excel打开:
scrapy crawl page_crawl -o article_data.csv新手避坑
重复执行命令会追加数据,导致数据重复,二次爬取前建议删除旧CSV文件。
六、数据持久化②:Pipeline管道工程化存储(CSV+MySQL双存储)
临时导出适合测试,正式项目必须使用管道Pipeline持久化。爬虫每产出一条数据,自动流经管道,实现自定义存储、数据清洗、去重筛选。
直接替换pipelines.py全部代码,实现本地CSV+MySQL数据库双保存:
import csvimport pymysql# CSV文件存储管道class CsvPipeline:# 爬虫启动时执行:初始化文件def open_spider(self, spider):self.file = open("article_list.csv", "w", encoding="utf-8-sig", newline="")self.writer = csv.DictWriter(self.file,fieldnames=["title", "link", "publish_time", "desc"])self.writer.writeheader()# 数据处理核心方法def process_item(self, item, spider):self.writer.writerow(dict(item))return item# 爬虫结束时执行:释放文件资源def close_spider(self, spider):self.file.close()# MySQL数据库存储管道class MysqlPipeline:def open_spider(self, spider):# 连接本地数据库,自行修改账号密码self.conn = pymysql.connect(host="127.0.0.1",port=3306,user="root",password="你的数据库密码",database="spider_data",charset="utf8mb4")self.cursor = self.conn.cursor()def process_item(self, item, spider):# 插入数据,重复链接自动忽略(link需要设唯一索引)sql = """INSERT IGNORE INTO article_table (title,link,publish_time,desc)VALUES(%s,%s,%s,%s)"""self.cursor.execute(sql,(item["title"], item["link"], item["publish_time"], item["desc"]))self.conn.commit()return itemdef close_spider(self, spider):self.cursor.close()self.conn.close()
七、数据库前置准备(必操作)
提前打开MySQL,执行以下建库建表语句,否则数据库入库报错:
CREATE DATABASE IF NOT EXISTS spider_data DEFAULT CHARSET utf8mb4;USE spider_data;CREATE TABLE IF NOT EXISTS article_table (id INT PRIMARY KEY AUTO_INCREMENT,title VARCHAR(500),link VARCHAR(800) UNIQUE,publish_time VARCHAR(100),desc TEXT)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
参数说明:link设置唯一索引,搭配INSERT IGNORE实现自动去重,杜绝重复数据入库。
八、开启管道+全局防爬配置(settings.py)
管道编写完成后,必须在配置文件中注册才能生效,同时开启基础防爬参数,避免被网站拦截。修改settings.py:
# 开启数据管道,数字代表执行优先级,越小越先执行ITEM_PIPELINES = {"my_spider.pipelines.CsvPipeline": 200,"my_spider.pipelines.MysqlPipeline": 300,}# 基础防爬配置ROBOTSTXT_OBEY = False # 关闭机器人协议拦截,很多站点会限制爬虫DOWNLOAD_DELAY = 1 # 每两次请求间隔1秒,模拟人工浏览,降低封IP风险# 伪装浏览器请求头 UADEFAULT_REQUEST_HEADERS = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"}
九、启动完整分页爬虫项目
项目根目录下执行启动命令,无需额外参数,自动分页爬取+双渠道存储:
scrapy crawl page_crawl运行效果
✅ 自动遍历全站分页数据,无需手动干预
✅ 本地自动生成CSV文件,完整保存所有数据
✅ 实时同步入库MySQL,自动去重、稳定落地
十、新手高频踩坑汇总(避坑必看)
1、爬虫只爬第一页,无法翻页
大概率是下一页Xpath匹配错误、未使用urljoin拼接链接;若网页为JS动态渲染,原生Scrapy无法获取下一页标签,需搭配Selenium中间件。
2、MySQL中文乱码
数据库连接编码、数据表编码必须统一为utf8mb4,兼容全部中文与特殊符号。
3、爬虫启动403访问被拒
未配置UA伪装、无请求延时,严格开启settings中的防爬基础配置。
4、数据字段为空报错
禁止直接使用extract_first(),统一使用get(default="")做空值兜底。
文末结语
分页爬取+数据持久化,是Scrapy框架从入门到实战的核心分水岭。
手写爬虫需要自己维护页码、循环逻辑、文件开关、数据库连接释放,代码冗余且极易出错。而Scrapy框架通过模块化设计,将调度、分页、存储、去重全部封装,开发者只需聚焦核心数据提取逻辑。
吃透本篇,你已经可以独立开发完整、稳定、可落地的企业级列表页爬虫项目,彻底脱离新手玩具代码!