关于 scrapy框架 详解

scrapy 是一个纯 Python 编写的异步爬虫框架,具备以下特点:

优势说明
异步高效基于 Twisted,非阻塞 IO
模块化各部分可灵活配置/替换
中间件机制支持代理、UA、cookie 控制等
强大的解析内置 XPath、CSS 提取器
自动去重Scheduler 内部维护请求 fingerprint
可扩展支持 Redis/MongoDB/Selenium 等集成

适合用于中大型项目,管理多个 Spider 和抓取流程。


一、Scrapy 架构图 & 核心原理

        ┌────────────────────────────────────┐│           Scrapy Engine 引擎       ││   (调度、分发请求与响应的控制中枢)  │└────────────────────────────────────┘▲          ▲│          │┌──────────────┘          └────────────────────┐▼                                               ▼
┌──────────────┐                             ┌─────────────────────┐
│ Scheduler    │                             │  Downloader          │
│ 调度器       │                             │ 下载器(发请求)     │
│ 维护请求队列 │                             └─────────────────────┘
└─────▲────────┘                                       ▲│                                                ││       ┌─────────────────────────────┐          │└──────►│ Downloader Middlewares 下载中间件│◄──────┘└─────────────────────────────┘▲│┌─────┴───────┐│ Request 请求│└────────────┘│▼┌─────────────┐│ Response 响应│└────┬────────┘│▼┌────────────────────────────────────┐│             Spider 爬虫类           ││    (处理响应,提取数据和生成新请求) │└────────────────┬───────────────────┘│▼┌────────────────────┐│  Item(提取数据)   │└───────┬────────────┘▼┌──────────────────────────┐│  Item Pipeline 管道       ││(保存数据到文件、数据库等)│└──────────────────────────┘

>工作流程步骤解释

  • >1. Spider 生成初始 Request 请求

    • start_urls = ['https://example.com']

    • 被送到引擎(Engine)

  • >2. Engine 把请求交给 Scheduler 调度器

    • 调度器负责排队请求,避免重复(有去重功能)

  • >3. Engine 从 Scheduler 取一个请求交给 Downloader 下载器

    • Downloader 通过 HTTP 请求抓网页(可带中间件,如代理)

  • >4. Downloader 下载完后返回 Response 给 Engine

  • >5. Engine 把 Response 给 Spider 的 parse() 方法

    • 写的 parse() 里会提取数据(Item)或继续发送新请求

  • >6. 提取的数据(Item)交给 Pipeline

    • Pipeline 可以把它存储到:文件、MongoDB、MySQL、Elasticsearch 等

  • >7. Spider 产生的新请求(Request)再次送入 Scheduler → 重复上面过程

>模拟完整流程(豆瓣爬虫举例)

假设爬豆瓣 Top250 页:

  • >1. Spider:创建第一个请求 Request("https://movie.douban.com/top250")

  • >2. Scheduler:收下请求排队

  • >3. Downloader:请求网站,返回 HTML

  • >4. Spider.parse():用 CSS/XPath 抽取电影名、评分

  • >5. 生成 Item:{'title': '肖申克的救赎', 'score': '9.7'}

  • >6. Pipeline:保存为 JSON

  • >7. 如果页面有“下一页”,parse() 再 yield 一个 Request(下一页链接),流程继续


二、Scrapy 项目结构

创建项目:

scrapy startproject myspider

结构如下:

myspider/                      ← Scrapy 项目根目录
├── scrapy.cfg                 ← Scrapy 配置文件(全局入口)
├── myspider/                 ← 项目 Python 包目录(真正的业务逻辑在这)
│   ├── __init__.py            ← 表明这是一个包
│   ├── items.py               ← 定义数据结构(Item 模型)
│   ├── middlewares.py         ← 下载中间件定义(如加代理)
│   ├── pipelines.py           ← 管道:保存数据(文件、数据库)
│   ├── settings.py            ← 项目配置文件(如 headers、限速、并发数)
│   └── spiders/               ← 存放所有 Spider 的目录
│       └── example.py         ← 一个 Spider 示例(爬虫脚本)

2.1 scrapy.cfg(项目运行配置文件)

位置:根目录
作用:告诉 Scrapy 你要运行哪个项目的设置文件。

内容示例:

[settings]
default = myspider.settings   ← 指定 settings.py 的位置[deploy]
# 用于部署到 scrapyd 时用,不影响本地运行

当运行 scrapy crawl xxx 命令时,它会先从这个文件找到项目配置。

2.2 myspider/(项目主模块目录)

这是 Scrapy 真正执行的业务模块,其中所有核心逻辑都写在这里。

1)__init__.py

让 Python 把 myspider/ 识别为模块包,没别的逻辑。

2)items.py:定义数据结构(类似数据表字段)

Scrapy 的数据提取不是直接用字典,而是专门定义一个 Item 类。

示例:

import scrapyclass MyspiderItem(scrapy.Item):title = scrapy.Field()author = scrapy.Field()date = scrapy.Field()

在 Spider 中提取数据时用:

item = MyspiderItem()
item['title'] = ...
item['author'] = ...
yield item

3)middlewares.py:下载中间件(拦截请求与响应)

Scrapy 支持在请求发出前、响应回来后做额外处理,例如:

  • 修改请求头(如 User-Agent)

  • 设置代理

  • 自动重试

  • 伪装成浏览器

示例:

class RandomUserAgentMiddleware:def process_request(self, request, spider):request.headers['User-Agent'] = 'YourUserAgent'

settings.py 中启用:

DOWNLOADER_MIDDLEWARES = {'myspider.middlewares.RandomUserAgentMiddleware': 543,
}

4)pipelines.py:数据管道(保存提取到的数据)

Scrapy 提取的数据通过 Item 传入管道中做进一步处理,比如:

  • 保存到 JSON、CSV

  • 存入数据库(MongoDB、MySQL)

  • 图片下载

示例:

class JsonWriterPipeline:def open_spider(self, spider):self.file = open('items.json', 'w', encoding='utf-8')def process_item(self, item, spider):self.file.write(str(item) + "\n")return itemdef close_spider(self, spider):self.file.close()

settings.py 启用:

ITEM_PIPELINES = {'myspider.pipelines.JsonWriterPipeline': 300,
}

5)settings.py:Scrapy 项目的配置中心

可以在这里设置:

配置项作用
ROBOTSTXT_OBEY是否遵守 robots 协议(开发建议设为 False)
DOWNLOAD_DELAY下载延迟(防止被封 IP)
CONCURRENT_REQUESTS最大并发请求数
DEFAULT_REQUEST_HEADERS请求头设置
ITEM_PIPELINES设置哪些 pipeline 被启用
DOWNLOADER_MIDDLEWARES设置中间件

示例片段:

BOT_NAME = 'myspider'ROBOTSTXT_OBEY = False
DOWNLOAD_DELAY = 1
CONCURRENT_REQUESTS = 16DEFAULT_REQUEST_HEADERS = {'User-Agent': 'Mozilla/5.0',
}ITEM_PIPELINES = {'myspider.pipelines.JsonWriterPipeline': 300,
}

6)spiders/:爬虫文件目录(每个爬虫类放一个 .py)

一个 Spider 类 = 一个网站的爬虫逻辑。

示例:

import scrapy
from myspider.items import MyspiderItemclass BookSpider(scrapy.Spider):name = "books"start_urls = ['https://books.example.com']def parse(self, response):for book in response.css('div.book'):item = MyspiderItem()item['title'] = book.css('h2::text').get()item['author'] = book.css('.author::text').get()yield item

运行爬虫:

scrapy crawl books

2.3 各模块作用表

位置作用是否需要改
scrapy.cfg项目入口配置一般不改
myspider/__init__.py标识模块不改
items.py定义数据字段必改
middlewares.py拦截请求/响应可选改
pipelines.py存储 Item可选改
settings.py设置并发、延迟等常用配置项要改
spiders/放爬虫脚本主战场,必须写

三、项目举例

实战目标

  • 抓取 某勾职位接口。

  • 提取字段:

    • 职位名、公司名、城市、薪资、学历、经验、公司规模

  • 自动翻页(1~5页)

  • 保存为 CSV 文件

第一步:创建项目

打开终端:

scrapy startproject lagou_spider
cd lagou_spider

第二步:定义字段(items.py)

编辑 lagou_spider/lagou_spider/items.py

import scrapyclass LagouSpiderItem(scrapy.Item):position = scrapy.Field()company = scrapy.Field()salary = scrapy.Field()city = scrapy.Field()exp = scrapy.Field()edu = scrapy.Field()company_size = scrapy.Field()

第三步:创建爬虫文件

cd lagou_spider/lagou_spider/spiders
touch lagou.py  # Windows 用户用编辑器创建 lagou.py 文件

编辑 lagou.py

import scrapy
import json
from lagou_spider.items import LagouSpiderItemclass LagouSpider(scrapy.Spider):name = 'lagou'allowed_domains = ['lagou.com']start_urls = ['https://www.lagou.com/jobs/list_python']def start_requests(self):for page in range(1, 6):  # 抓取前 5 页url = 'https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false'headers = {'Referer': 'https://www.lagou.com/jobs/list_python','User-Agent': 'Mozilla/5.0','Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',}data = {'first': 'true' if page == 1 else 'false','pn': str(page),'kd': 'python'}yield scrapy.FormRequest(url=url,formdata=data,headers=headers,callback=self.parse)def parse(self, response):data = json.loads(response.text)jobs = data['content']['positionResult']['result']for job in jobs:item = LagouSpiderItem()item['position'] = job['positionName']item['company'] = job['companyFullName']item['salary'] = job['salary']item['city'] = job['city']item['exp'] = job['workYear']item['edu'] = job['education']item['company_size'] = job['companySize']yield item

第四步:配置 pipeline 保存 CSV

编辑 lagou_spider/lagou_spider/pipelines.py

import csvclass CsvPipeline:def open_spider(self, spider):self.file = open('lagou_jobs.csv', 'w', newline='', encoding='utf-8-sig')self.writer = csv.writer(self.file)self.writer.writerow(['职位', '公司', '薪资', '城市', '经验', '学历', '公司规模'])def process_item(self, item, spider):self.writer.writerow([item['position'],item['company'],item['salary'],item['city'],item['exp'],item['edu'],item['company_size']])return itemdef close_spider(self, spider):self.file.close()

第五步:修改配置 settings.py

编辑 lagou_spider/lagou_spider/settings.py,添加或修改:

ROBOTSTXT_OBEY = False
DOWNLOAD_DELAY = 1.5  # 降低请求频率,防止封 IP
DEFAULT_REQUEST_HEADERS = {'User-Agent': 'Mozilla/5.0'
}
ITEM_PIPELINES = {'lagou_spider.pipelines.CsvPipeline': 300,
}

第六步:运行爬虫

在终端中运行:

scrapy crawl lagou

第七步:查看结果(lagou_jobs.csv)

输出示例(CSV 文件):

职位公司薪资城市经验学历公司规模
Python开发工程师字节跳动15k-30k北京3-5年本科10000人以上
后端Python工程师腾讯20k-40k深圳5-10年本科5000-10000人

项目结构参考

lagou_spider/
├── scrapy.cfg
├── lagou_spider/
│   ├── __init__.py
│   ├── items.py
│   ├── pipelines.py
│   ├── settings.py
│   └── spiders/
│       └── lagou.py

注意事项

问题说明
某勾有反爬添加 DOWNLOAD_DELAY,5 页以内一般不封
接口变化抓的是 JSON 接口,稳定性比页面 HTML 好
抓太多IP 会被封,建议加代理池后使用
数据为空设置 Referer + UA + Content-Type 后就正常了

后续可拓展功能

功能方法
添加代理池中间件 process_request() 设置
分布式scrapy-redis 实现
存 MongoDB改 pipeline 用 pymongo 写入
接入前端展示输出 JSON/数据库配合前端页面展示

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/88004.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/88004.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DHCP中继实验及其核心原理

DHCP 中继(DHCP Relay)是一种允许跨网段分配 IP 地址的技术,无需在每个子网部署 DHCP 服务器。以下是其原理和配置方法的详细说明:一、核心原理1. 为什么需要 DHCP 中继?问题:DHCP 客户端通过广播&#xff…

ABP VNext + RediSearch:微服务级全文检索

ABP VNext RediSearch:微服务级全文检索 🚀 📚 目录ABP VNext RediSearch:微服务级全文检索 🚀📚 一、背景与动机 🚀🛠️ 二、环境与依赖 🐳2.1 Docker Compose 启动 R…

TensorFlow深度学习实战——基于自编码器构建句子向量

TensorFlow深度学习实战——基于自编码器构建句子向量 0. 前言1. 句子向量2. 基于自编码器构建句子向量2.1 数据处理2.2 模型构建与训练 3. 模型测试相关链接 0. 前言 在本节中,我们将构建和训练一个基于长短期记忆 (Long Short Term Memory, LSTM) 的自编码器&…

C语言使用Protobuf进行网络通信

笔者前面博文Go语言网络游戏服务器模块化编程介绍了Go语言在开发网络游戏时如何进行模块化编程,在其中使用了Protobuf进行网络通信。在Protobuf官方实现中并没有生成C语言的实现,不过有一个开源的protobuf-c可以使用。 先来看看protobuf-c生成的代码&am…

vue3 随手笔记12--组件通信方式9/5--useAttrs

一 什么是useAttrsuseAttrs 是 Vue 3 Composition API 中提供的一个函数,它属于 Vue 的组合式 API 工具集的一部分。通过 useAttrs,你可以访问传递给组件但未被声明为 props 的所有属性。这对于处理非 prop 特性(attributes)特别有…

HumanRisk-自动化安全意识与合规教育平台方案

权威数据显示,74%以上的数据泄露与网络安全事件归根结底与人为因素有关,60%以上的网络安全事件是由内部人员失误造成的。这一现状揭示了一个核心命题:网络安全威胁正从技术漏洞转向“人为因素风险”。Gartner的调查发现,即便接受了…

2025年食品科学与健康大数据国际会议(SHBD 2025)

2025年食品科学与健康大数据国际会议 2025 International Conference on Food Science and Health Big Data(一)大会信息 会议简称:ICFSHBD 2025 大会地点:中国上…

CompareFace人脸识别算法环境部署

一、docker 安装 步骤1:启用系统功能 右键开始菜单 → 应用和功能 → 点击 程序和功能 → 勾选 Hyper-V 和 Windows子系统Linux 步骤2:获取安装包 访问Docker官网安装包下载页 ,下载「Docker Desktop Installer.rar」压缩包 步骤3&#…

STM32固件升级设计——内部FLASH模拟U盘升级固件

目录 一、功能描述 1、BootLoader部分: 2、APP部分: 二、BootLoader程序制作 1、分区定义 2、 主函数 3、配置USB 4、配置fatfs文件系统 5、程序跳转 三、APP程序制作 四、工程配置(默认KEIL5) 五、运行测试 结束语…

操作系统引导过程

操作系统引导是指计算机利用 CPU 运行特定程序,通过程序识别硬盘,识别硬盘分区,识别硬盘分区上的操作系统,最后通过程序启动操作系统。 引导流程(8步核心环节) 1. 激活CPU 加电后CPU自动读取 ROM中的Boot…

Safetensors与大模型文件格式全面解析

Safetensors是一种专为存储大型张量数据设计的文件格式,由Hugging Face团队开发,旨在提供安全高效的模型参数存储解决方案。下面将详细介绍Safetensors格式及其特点,并全面梳理当前主流的大模型文件格式。 一、Safetensors格式详解 1. 基本概…

分布式理论:CAP、Base理论

目录 1、CAP理论 1.1、介绍 1.2、CAP的三种选择 1.3、CAP的注意事项 2、BASE理论 2.1、定义介绍 2.2、最终一致性的介绍 2.3、BASE的实现方式 2.4、与ACID的对比 3、CAP与BASE的联系 4、如何选择CAP 前言 在分布式系统中,CAP理论和BASE理论是指导系统设计…

【最新】飞算 JavaAl安装、注册,使用全流程,让ai自己给你写代码,解放双手

目录 飞算 JavaAl 产品介绍 安装飞算 JavaAl 第一步:点击 File->Setting 第二步:点击 Plugins 第三步:搜索 CalEx-JavaAI 第四步:点击 Install 进行安装 第五步:点击 Install ,查看安装好的飞算…

无人设备遥控器之姿态控制算法篇

无人设备遥控器的姿态控制算法通过传感器数据融合、控制算法优化和执行机构调节实现动态平衡,核心算法包括PID控制、自适应控制、模型预测控制(MPC),以及数据融合中的互补滤波和卡尔曼滤波,同时涉及四元数算法和深度强…

【加解密与C】Base系列(三)Base85

Base85 编码简介 Base85(也称为 Ascii85)是一种二进制到文本的编码方案,用于将二进制数据转换为可打印的ASCII字符。它的效率高于Base64,但生成的字符串可能包含特殊字符(如引号或反斜杠),需在…

Docker企业级应用:从入门到生产环境最佳实践

一、Docker核心概念与架构 1.1 Docker技术栈 #mermaid-svg-CUEiyGo05ZYG524v {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-CUEiyGo05ZYG524v .error-icon{fill:#552222;}#mermaid-svg-CUEiyGo05ZYG524v .error-te…

8、保存应用数据

目录用户首选项的使用用户首选项主要API用户首选项开发流程用户首选项开发实践关系型数据库的使用关系型数据库工作流程关系型数据库开发实践用户首选项的使用 用户首选项主要API 用户首选项开发流程 成功的获取了一个名为myStore的Preferences实例 保存了一个键值对&#x…

(C++)list列表相关基础用法(C++教程)(STL库基础教程)

源代码&#xff1a;#include <iostream> #include <list>using namespace std;int main(){list<int> numbers{10,20,30};numbers.push_front(5);numbers.push_back(40);auto it numbers.begin();advance(it,2);numbers.insert(it,15);cout<<"该列…

Spring CGLIB私有方法访问成员变量为null问题

场景 代码 RestController public class TestJob {Autowiredprivate XxService xxService;XxlJob("testCGLIB")private void doTest(){System.out.println("方法调用");System.out.println("成员变量注入:"(xxService!null));this.doInnerTest()…

Paimon本地表查询引擎LocalTableQuery详解

LocalTableQueryLocalTableQuery 是 Paimon 中实现本地化、带缓存的表查询的核心引擎。它的主要应用场景是 Flink 中的 Lookup Join。当 Flink 作业需要根据一个流中的 Key 去关联一个 Paimon 维表时&#xff0c;LocalTableQuery 可以在 Flink 的 TaskManager 节点上&#xff0…