文章目录
- 一、Scrapy核心优势与应用场景
- (一)为什么选择Scrapy?
- (二)Python典型应用场景
- 二、Python环境搭建:零基础快速上手
- (一)Python基础环境要求
- (二)Windows系统安装步骤
- 1. 安装Python并配置环境变量
- 2. 安装Python依赖库
- 3. 验证安装
- (三)Linux(CentOS 7)安装步骤
- (四)常见安装问题解决
- 三、Scrapy核心架构与工作流程
- (一)核心组件详解
- (二)完整工作流程
- 四、第一个Scrapy爬虫:爬取豆瓣Top250电影数据
- (一)创建爬虫项目
- (二)定义数据模型(items.py)
- (三)编写爬虫逻辑(douban.py)
- (四)配置全局设置(settings.py)
- (五)数据持久化(pipelines.py)
- (六)运行爬虫
- 五、核心进阶技巧:解决爬取中的常见问题
- (一)XPath/BeautifulSoup数据提取优化
- (二)处理动态加载页面(JS渲染)
- (三)反反爬策略实战
- 1. 随机User-Agent池
- 2. 代理IP池配置
- 3. Cookie池与登录态保持
- (四)分布式爬取(Scrapy-Redis)
- 六、爬虫运维与性能优化
- (一)性能调优参数
- (二)监控与日志分析
- (三)合规性注意事项
- 七、常见问题解答
- 1. Scrapy爬取的数据出现乱码?
- 2. 爬虫运行中突然停止,无报错?
- 3. 如何爬取需要验证码的页面?
- 4. Item Pipeline不生效?
- 总结
Scrapy作为Python生态中最成熟的专业爬虫框架,凭借高性能、可扩展性和模块化设计,成为数据采集领域的主流选择。无论是电商数据爬取、舆情监控还是行业数据分析,掌握Scrapy都能大幅提升爬虫开发效率。
一、Scrapy核心优势与应用场景
(一)为什么选择Scrapy?
相比requests+BeautifulSoup的简易爬虫组合,Scrapy具备不可替代的优势:
- 异步非阻塞IO:基于Twisted引擎,单进程可并发处理数百个请求,爬取效率提升5-10倍;
- 完整的爬虫生命周期管理:内置请求调度、数据清洗、持久化存储等模块,无需重复造轮子;
- 强大的扩展性:支持中间件自定义、信号机制、分布式爬取(结合Scrapy-Redis);
- 内置反爬应对方案:可配置请求延迟、User-Agent池、Cookie池等;
- 数据导出便捷:一键导出JSON、CSV、Excel或写入数据库。
(二)Python典型应用场景
- 电商平台商品数据采集(价格、销量、评价);
- 新闻资讯、社交媒体内容爬取与舆情分析;
- 招聘网站职位信息、房产数据聚合;
- 学术论文、专利数据批量抓取;
- 竞品数据监控与分析。
二、Python环境搭建:零基础快速上手
(一)Python基础环境要求
- Python版本:3.7-3.10(Scrapy 2.10+对3.11兼容性待优化);
- 操作系统:Windows/Linux/macOS(Linux稳定性最佳,推荐生产环境使用);
- 依赖库:Twisted、pywin32(Windows)、cryptography等。
(二)Windows系统安装步骤
1. 安装Python并配置环境变量
下载Python 3.13版本(https://pan.quark.cn/s/bce37ebd7f70),安装时勾选“Add Python 3.13 to PATH”。
2. 安装Python依赖库
打开CMD命令行,执行以下命令:
# 升级pippython -m pipinstall--upgrade pip# 安装pywin32(Windows必备)pipinstallpywin32# 安装Scrapypipinstallscrapy==2.10.13. 验证安装
执行scrapy version,输出如下信息则安装成功:
Scrapy 2.10.1 - no active project Python 3.9.18 (tags/v3.9.18:2e7e50c, Sep 1 2023, 18:50:44) [MSC v.1937 64 bit (AMD64)] Platform Windows-10-10.0.19045-SP0(三)Linux(CentOS 7)安装步骤
# 安装依赖包yuminstall-y gcc python3-devel libxml2-devel libxslt-devel# 安装Scrapypip3installscrapy==2.10.1# 验证scrapy version(四)常见安装问题解决
- Windows下提示“找不到VCRUNTIME140.dll”:安装Microsoft Visual C++ 2019运行库(https://aka.ms/vs/17/release/vc_redist.x64.exe);
- Linux下Twisted安装失败:先执行
pip3 install twisted==22.10.0指定版本,再安装Scrapy; - 权限不足:Linux/Mac添加
--user参数(pip3 install --user scrapy),Windows以管理员身份运行CMD。
三、Scrapy核心架构与工作流程
(一)核心组件详解
Scrapy的架构采用模块化设计,各组件分工明确:
| 组件名称 | 核心作用 |
|---|---|
| 引擎(Engine) | 核心调度器,协调所有组件工作 |
| 调度器(Scheduler) | 接收引擎的请求,按优先级和去重规则管理请求队列 |
| 下载器(Downloader) | 基于Twisted下载网页内容,支持异步、代理、请求重试 |
| 爬虫(Spiders) | 定义爬取规则:起始URL、数据提取规则、链接跟进规则 |
| 项目管道(Item Pipeline) | 处理爬取到的数据:清洗、验证、去重、持久化(写入数据库/文件) |
| 下载中间件(Downloader Middlewares) | 拦截请求/响应:添加代理、修改请求头、处理cookie、反反爬 |
| 爬虫中间件(Spider Middlewares) | 处理爬虫输入(响应)和输出(请求/数据):过滤无效请求、修改数据 |
(二)完整工作流程
- 引擎向爬虫获取起始URL,封装成请求对象交给调度器;
- 调度器将请求排序后,返回给引擎;
- 引擎把请求交给下载器,下载器通过下载中间件发送请求,获取响应;
- 下载器将响应通过爬虫中间件交给爬虫;
- 爬虫解析响应,提取数据(交给Item Pipeline)和新的URL(交给调度器);
- 重复步骤2-5,直到调度器中无待处理请求,爬虫结束。
四、第一个Scrapy爬虫:爬取豆瓣Top250电影数据
(一)创建爬虫项目
# 创建项目scrapy startproject douban_movie# 进入项目目录cddouban_movie# 创建爬虫文件(指定域名避免爬取无关网站)scrapy genspider douban top250.douban.com项目目录结构说明:
douban_movie/ ├── douban_movie/ # 项目核心目录 │ ├── __init__.py │ ├── items.py # 数据模型定义 │ ├── middlewares.py # 中间件配置 │ ├── pipelines.py # 数据处理管道 │ ├── settings.py # 全局配置 │ └── spiders/ # 爬虫文件目录 │ ├── __init__.py │ └── douban.py # 爬虫逻辑文件 └── scrapy.cfg # 项目配置(无需修改)(二)定义数据模型(items.py)
提前定义数据字段,规范爬取数据格式:
importscrapyclassDoubanMovieItem(scrapy.Item):# 电影标题title=scrapy.Field()# 评分score=scrapy.Field()# 评价人数comment_num=scrapy.Field()# 简介intro=scrapy.Field()# 电影链接link=scrapy.Field()(三)编写爬虫逻辑(douban.py)
importscrapyfromdouban_movie.itemsimportDoubanMovieItemclassDoubanSpider(scrapy.Spider):# 爬虫名称(必须唯一)name='douban'# 允许爬取的域名allowed_domains=['top250.douban.com']# 起始URLstart_urls=['https://top250.douban.com/top250']defparse(self,response):# 提取当前页所有电影条目movie_list=response.xpath('//ol[@class="grid_view"]/li')formovieinmovie_list:# 实例化数据模型item=DoubanMovieItem()# 提取数据(XPath语法)item['title']=movie.xpath('.//span[@class="title"][1]/text()').extract_first()item['score']=movie.xpath('.//span[@class="rating_num"]/text()').extract_first()item['comment_num']=movie.xpath('.//div[@class="star"]/span[4]/text()').extract_first().replace('人评价','')item['intro']=movie.xpath('.//span[@class="inq"]/text()').extract_first()item['link']=movie.xpath('.//a/@href').extract_first()# 提交数据到管道yielditem# 提取下一页链接next_page=response.xpath('//span[@class="next"]/a/@href').extract_first()ifnext_page:# 拼接完整URLnext_url='https://top250.douban.com/top250'+next_page# 发送下一页请求,回调parse方法继续解析yieldscrapy.Request(url=next_url,callback=self.parse)(四)配置全局设置(settings.py)
修改关键配置,提升爬取稳定性:
# 遵守robots协议(默认True,反爬可改为False)ROBOTSTXT_OBEY=False# 请求延迟(避免高频请求被封IP)DOWNLOAD_DELAY=2# 随机User-Agent(模拟浏览器)USER_AGENT='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'# 启用管道(数字越小优先级越高)ITEM_PIPELINES={'douban_movie.pipelines.DoubanMoviePipeline':300,}# 日志级别(DEBUG/INFO/WARNING/ERROR)LOG_LEVEL='INFO'(五)数据持久化(pipelines.py)
将爬取的数据写入CSV文件:
importcsvclassDoubanMoviePipeline:def__init__(self):# 打开文件,指定编码避免中文乱码self.file=open('douban_top250.csv','w',newline='',encoding='utf-8')self.writer=csv.DictWriter(self.file,fieldnames=['title','score','comment_num','intro','link'])# 写入表头self.writer.writeheader()defprocess_item(self,item,spider):# 写入数据行self.writer.writerow(dict(item))returnitemdefclose_spider(self,spider):# 爬虫结束关闭文件self.file.close()(六)运行爬虫
# 执行爬虫(指定爬虫名称)scrapy crawl douban运行完成后,项目根目录会生成douban_top250.csv文件,包含所有电影数据。
五、核心进阶技巧:解决爬取中的常见问题
(一)XPath/BeautifulSoup数据提取优化
XPath精准定位:
- 避免使用
//*等模糊路径,优先通过class/id定位; - 使用
extract_first()替代extract()[0],避免索引越界; - 示例:
response.xpath('//div[@class="content"]/text()').extract_first().strip()
- 避免使用
结合BeautifulSoup解析:
若XPath不熟练,可在爬虫中引入BeautifulSoup:frombs4importBeautifulSoupdefparse(self,response):soup=BeautifulSoup(response.text,'lxml')title=soup.find('span',class_='title').text
(二)处理动态加载页面(JS渲染)
Scrapy默认无法解析JS动态渲染的内容,解决方案:
方案1:分析接口直接爬取(推荐)
通过浏览器F12“网络”面板,找到数据接口(通常是JSON格式),直接请求接口获取数据,避免解析HTML。方案2:结合Scrapy-Splash
安装Splash(需Docker环境):docker run -p8050:8050 scrapinghub/splash安装Scrapy-Splash:
pipinstallscrapy-splash配置settings.py:
SPLASH_URL='http://localhost:8050'DOWNLOADER_MIDDLEWARES={'scrapy_splash.SplashCookiesMiddleware':723,'scrapy_splash.SplashMiddleware':725,'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware':810,}SPIDER_MIDDLEWARES={'scrapy_splash.SplashDeduplicateArgsMiddleware':100,}DUPEFILTER_CLASS='scrapy_splash.SplashAwareDupeFilter'爬虫中使用Splash:
yieldscrapy.Request(url=url,callback=self.parse,meta={'splash':{'args':{'wait':2},# 等待2秒加载JS'endpoint':'render.html',}})
(三)反反爬策略实战
1. 随机User-Agent池
修改middlewares.py,添加自定义下载中间件:
importrandomclassRandomUserAgentMiddleware:# 自定义User-Agent列表USER_AGENTS=['Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/114.0.0.0 Safari/537.36','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Firefox/114.0','Mozilla/5.0 (iPhone; CPU iPhone OS 16_5 like Mac OS X) Safari/605.1.15']defprocess_request(self,request,spider):# 随机选择User-Agentrequest.headers['User-Agent']=random.choice(self.USER_AGENTS)在settings.py启用中间件:
DOWNLOADER_MIDDLEWARES={'douban_movie.middlewares.RandomUserAgentMiddleware':543,}2. 代理IP池配置
classProxyMiddleware:PROXIES=['http://123.45.67.89:8080','http://98.76.54.32:8888',]defprocess_request(self,request,spider):request.meta['proxy']=random.choice(self.PROXIES)3. Cookie池与登录态保持
通过start_requests方法模拟登录:
defstart_requests(self):# 登录URLlogin_url='https://accounts.douban.com/login'# 登录参数data={'form_email':'your_email','form_password':'your_password'}# 发送登录请求yieldscrapy.FormRequest(url=login_url,formdata=data,callback=self.after_login)defafter_login(self,response):# 登录成功后,发送起始请求yieldscrapy.Request(url=self.start_urls[0],callback=self.parse)(四)分布式爬取(Scrapy-Redis)
针对海量数据爬取,结合Scrapy-Redis实现多机分布式:
- 安装依赖:
pip install scrapy-redis - 修改settings.py:
# 启用Redis调度器SCHEDULER="scrapy_redis.scheduler.Scheduler"# 启用Redis去重DUPEFILTER_CLASS="scrapy_redis.dupefilter.RFPDupeFilter"# Redis连接配置REDIS_URL='redis://localhost:6379/0'# 爬取完成后不清除Redis数据SCHEDULER_PERSIST=True - 启动Redis服务,多台机器运行同一爬虫即可实现分布式爬取。
六、爬虫运维与性能优化
(一)性能调优参数
在settings.py中调整以下参数,提升爬取效率:
# 并发请求数(根据服务器性能调整,默认16)CONCURRENT_REQUESTS=32# 单域名并发数(避免给目标服务器压力过大)CONCURRENT_REQUESTS_PER_DOMAIN=8# 单IP并发数CONCURRENT_REQUESTS_PER_IP=4# 请求超时时间(秒)DOWNLOAD_TIMEOUT=10# 重试次数RETRY_TIMES=3# 重试状态码RETRY_HTTP_CODES=[500,502,503,504,408](二)监控与日志分析
- 日志分析:通过
scrapy crawl douban --logfile=douban.log将日志写入文件,分析请求失败原因; - 状态监控:使用Scrapy内置的
stats模块,在爬虫中打印关键指标:defclose(self,reason):# 打印爬取统计信息print("爬取总请求数:",self.crawler.stats.get_value('downloader/request_count'))print("爬取成功数:",self.crawler.stats.get_value('downloader/request_success_count'))print("爬取失败数:",self.crawler.stats.get_value('downloader/request_failure_count'))
(三)合规性注意事项
- 遵守网站
robots.txt协议,避免爬取隐私数据; - 控制爬取频率,避免给目标服务器造成压力;
- 爬取数据仅用于学习/合规分析,禁止商用或恶意攻击;
- 针对需要登录的网站,避免批量注册账号,遵守用户协议。
七、常见问题解答
1. Scrapy爬取的数据出现乱码?
答:检查响应编码,在parse方法中添加response.encoding = 'utf-8';写入文件时指定编码为utf-8。
2. 爬虫运行中突然停止,无报错?
答:大概率是被目标网站封IP,添加代理IP池和请求延迟;检查目标网站是否有验证码拦截。
3. 如何爬取需要验证码的页面?
答:方案1:对接第三方打码平台(如超级鹰);方案2:训练机器学习模型识别验证码;方案3:使用selenium模拟手动输入。
4. Item Pipeline不生效?
答:检查settings.py中ITEM_PIPELINES是否启用,优先级数字是否合理(1-1000);确保爬虫中yield item正确提交数据。
总结
Scrapy的核心价值在于“标准化”和“高性能”,掌握其核心架构和中间件机制,能解决90%以上的爬虫开发场景。入门阶段重点掌握数据提取和基础配置,进阶阶段需聚焦反反爬、分布式和性能优化。建议从实际场景出发(如爬取行业数据、个人兴趣数据),通过实战加深对框架的理解,同时始终遵守网络爬虫的合规性原则。