本文將帶你從零開始,借助 Feapder 快速搭建一個企業級招聘信息數據管道。在“基礎概念”部分,我們先了解什么是數據管道和 Feapder;“生動比喻”用日常場景幫助你快速理解爬蟲組件;“技術場景”介紹本項目中如何使用代理等采集策略;“實戰案例”通過完整代碼演示采集 51job 招聘信息并分類存儲;最后在“擴展閱讀”推薦一些進一步學習的資源。無論你是非技術背景的產品經理,還是校園里的同學,都能輕松上手,快速構建自己的企業級爬蟲管道。
一、基礎概念
1. 什么是數據管道?
- 數據管道(Data Pipeline)指的是從數據源(如網頁、API)到數據倉庫(如數據庫、文件)的整個流轉過程,通常包括數據獲取、清洗、存儲和監控。
- 在企業級場景下,管道需要穩定可靠、易于擴展,并支持重試、分布式、監控告警等能力。
2. 為什么選 Feapder?
- 輕量易用:基于 Scrapy 設計理念,但更貼合現代 Python 開發習慣。
- 分布式支持:內置分布式隊列和調度,水平擴展無壓力。
- 插件豐富:支持自定義中間件、Pipeline,持久化、監控簡單接入。
- 示例生態:官方及社區提供多種行業示例,快速上手。
二、生動比喻
想象你要送快遞:
- 分揀中心:接收并整理包裹(任務調度)
- 配送員:拿著包裹去各個地址(爬蟲 Worker)
- 快遞柜:存放收集好的包裹(Pipeline 存儲)
- 后臺系統:監控每個包裹的狀態(監控告警)
Feapder 就是整個快遞系統的“物流總控”,幫你把每個環節串起來,保證數據順利、穩定地流轉到最終存儲。
三、技術場景
在企業級爬蟲中,我們常常會遇到以下需求:
1. 使用代理 IP
- 提升并發時避免 IP 限流和封禁
- 引入爬蟲代理:
# 億牛云爬蟲代理示例 www.16yun.cn
域名: proxy.16yun.cn
端口: 12345
用戶名: 16YUN
密碼: 16IP
2. 設置 Cookie 和 User-Agent
- Cookie:保持登錄態或跑通多頁
- User-Agent:模擬瀏覽器請求,降低反爬幾率
Feapder 支持在中間件中統一管理這些參數,代碼簡潔、易維護。
四、實戰案例:采集 51job 企業招聘信息
下面我們以 https://www.51job.com 為例,演示如何用 Feapder 搭建完整的爬蟲管道,采集崗位名稱、職位信息、工作地址、薪資待遇,并分類存儲到本地 JSON 文件。
1. 環境準備
# 安裝 Feapder 及依賴
pip install feapder requests
2. 項目結構
feapder_job_pipeline/
├── spider.py # 主爬蟲腳本
├── settings.py # 配置文件
└── pipelines.py # 數據存儲模塊
3. 配置文件 settings.py
# settings.py# ---------- 分布式及隊列配置(可選) ----------
# REDIS_HOST = "127.0.0.1"
# REDIS_PORT = 6379
# REDIS_PASSWORD = None# ---------- 代理設置 億牛云代理示例 www.16yun.cn------
PROXY = {"domain": "proxy.16yun.cn", # 億牛云代理域名"port": 8100, # 代理端口"username": "16YUN", # 代理用戶名"password": "16IP", # 代理密碼
}# ---------- 中間件配置 ----------
DOWNLOADER_MIDDLEWARES = {# 自定義代理中間件"middlewares.ProxyMiddleware": 500,# Feapder 默認 UserAgent 中間件# "feapder.downloadermiddleware.useragent.UserAgentMiddleware": 400,
}# ---------- Pipeline 配置 ----------
ITEM_PIPELINES = {"pipelines.JsonPipeline": 300,
}
4. 自定義中間件 middlewares.py
# middlewares.py
import base64
from feapder import Requestclass ProxyMiddleware:"""通過億牛云代理發送請求的中間件"""def process_request(self, request: Request):# 構造代理認證字符串auth_str = f"{request.setting.PROXY['username']}:{request.setting.PROXY['password']}"b64_auth = base64.b64encode(auth_str.encode()).decode()# 設置 request.meta 中的 proxyrequest.request_kwargs.setdefault("proxies", {"http": f"http://{request.setting.PROXY['domain']}:{request.setting.PROXY['port']}","https": f"http://{request.setting.PROXY['domain']}:{request.setting.PROXY['port']}"})# 注入 Proxy-Authorization 頭request.request_kwargs.setdefault("headers", {})["Proxy-Authorization"] = f"Basic {b64_auth}"return request
5. 數據存儲 pipelines.py
# pipelines.py
import json
import os
from feapder import Itemclass JobItem(Item):"""定義崗位信息結構"""def __init__(self):self.position = Noneself.company = Noneself.location = Noneself.salary = Noneclass JsonPipeline:"""將數據按照公司分類存儲到 JSON 文件"""def open_spider(self, spider):# 創建存儲目錄self.base_path = spider.setting.get("DATA_PATH", "./data")os.makedirs(self.base_path, exist_ok=True)def process_item(self, item: JobItem, spider):# 按公司名稱分類存儲company = item.company or "unknown"file_path = os.path.join(self.base_path, f"{company}.json")# 追加寫入with open(file_path, "a", encoding="utf-8") as f:f.write(json.dumps(dict(item), ensure_ascii=False) + "\n")return item
6. 爬蟲腳本 spider.py
# spider.py
from feapder import Spider, Request
from pipelines import JobItem
import randomclass JobSpider(Spider):"""Feapder 爬蟲:采集 51job 企業招聘信息"""def start_requests(self):# 入口 URL,搜索“Python 開發”崗位url = "https://search.51job.com/list/000000,000000,0000,00,9,99,Python開發,2,1.html"yield Request(url, callback=self.parse_list)def parse_list(self, request, response):# 解析列表頁中的每個崗位鏈接for job in response.xpath("//div[@class='el']/p[@class='t1']/span/a"):job_url = job.xpath("./@href").extract_first()yield Request(job_url, callback=self.parse_detail)# 分頁(示例:最多采集前 5 頁)if int(request.url.split(",")[-1].split(".")[0]) < 5:next_page = int(request.url.split(",")[-1].split(".")[0]) + 1next_url = request.url.replace(f",{int(request.url.split(',')[-1].split('.')[0])}.html", f",{next_page}.html")yield Request(next_url, callback=self.parse_list)def parse_detail(self, request, response):"""解析崗位詳情頁"""item = JobItem()item.position = response.xpath("//h1/text()").extract_first().strip() # 崗位名稱item.company = response.xpath("//a[@class='catn']/text()").extract_first().strip() # 公司名稱item.location = response.xpath("//span[@class='lname']/text()").extract_first().strip() # 工作地點item.salary = response.xpath("//span[@class='salary']/text()").extract_first().strip() # 薪資待遇yield itemdef download_midware(self, request):"""在請求中注入 Cookie 與 User-Agent"""headers = {# 隨機選擇常見瀏覽器 UA"User-Agent": random.choice(["Mozilla/5.0 (Windows NT 10.0; Win64; x64)...","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)..."]),# 示例 Cookie,可根據需要替換"Cookie": "your_cookie_string_here"}request.request_kwargs.setdefault("headers", {}).update(headers)return requestif __name__ == "__main__":JobSpider(**{"project_name": "feapder_job_pipeline",# 可選:指定本地分布式隊列# "redis_key": "job_spider_requests",# "processes": 4,}).start()
7. 運行與結果
python spider.py
- 運行后,
./data/
目錄下會出現以公司名命名的 JSON 文件,每行一條崗位信息。
五、擴展閱讀
- Feapder 官方文檔:https://feapder.com/
- Scrapy 官方文檔(原理參考):https://docs.scrapy.org/
- 爬蟲代理使用指引:登錄億牛云官網查看“文檔中心”
- 同類案例:使用 Playwright 架構多語言爬蟲(可對比)
通過本文演示,你已經掌握了如何用 Feapder 快速構建一個帶有代理、Cookie、User-Agent 的企業級爬蟲管道,并能將數據分類存儲。接下來可以嘗試接入數據庫、監控告警,或將爬蟲部署到 Kubernetes 集群,打造真正的生產級數據管道。