關于 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
英文地址,請注明出處:http://en.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…