Funspider 分布式爬虫框架概览
一、核心特性
1.1 数据入库机制
ItemBuffer 批量入库设计
借鉴 Feapder 的 ItemBuffer 机制,实现高效的批量数据入库:
python
class ItemBuffer:
"""
数据缓冲管理器
功能:
- 批量缓冲:数据达到阈值后批量写入,减少数据库IO
- 多 Pipeline 支持:同时支持 MySQL、MongoDB、Elasticsearch 等
- 失败重试:入库失败自动重试,超过次数存入 Redis
- 去重处理:支持内存去重和 Redis 去重
"""
def __init__(self, spider_name: str,
batch_size: int = 100,
max_retry_times: int = 3):
self._items_queue = Queue(maxsize=10000)
self._pipelines = []
self._dedup_cache = set() # 内存去重
self.batch_size = batch_size
self.max_retry_times = max_retry_times
核心流程:
- 数据收集 :解析方法
yield Item()后,Item 进入队列 - 批量缓冲 :队列达到
batch_size或超时触发刷新 - 去重过滤 :基于
fingerprint进行去重 - Pipeline 链式处理:按优先级依次调用 Pipeline
- 失败重试:失败后重试,超过次数存入 Redis
代码示例:
python
# 在爬虫中使用
def parse_detail(self, request, response):
item = Item()
item.table_name = 'products'
item.title = response.xpath('//h1/text()').get()
item.price = response.xpath('//span[@class="price"]/text()').get()
yield item # 自动进入 ItemBuffer
1.2 去重机制
继承 Feapder 的去重方案
支持多种去重策略,兼容 Feapder 的去重过滤器:
python
from funspider.dedup import BloomFilter, ExpireFilter
# 1. 布隆过滤器(内存高效)
dedup = BloomFilter(
redis_url='redis://localhost:6379/0',
key='spider:dedup:products',
bit_size=10000000 # 1000万位
)
# 2. 带过期时间的去重(适合增量爬取)
dedup = ExpireFilter(
redis_url='redis://localhost:6379/0',
key='spider:dedup:products',
expire_time=86400 # 24小时过期
)
去重指纹生成:
python
class Item:
@property
def fingerprint(self) -> str:
"""生成数据指纹用于去重"""
data = {}
for key, value in self.__dict__.items():
if not key.startswith('_'):
data[key] = value
fingerprint_str = json.dumps(data, sort_keys=True, ensure_ascii=False)
return hashlib.md5(fingerprint_str.encode()).hexdigest()
Request 去重:
python
# Funboost 自带的消息去重机制
booster.publish(
request.to_dict(),
task_id=task_id,
# Funboost 会根据 task_id 自动去重
)
二、框架定位与局限性
2.1 与 其他爬虫框架相比 对比
缺少的功能:
- AirSpider(轻量级爬虫)
- Feapder 的 AirSpider 支持单脚本运行,无需 Redis/MySQL
- Funspider 必须依赖 Redis 作为消息队列,不适合简单任务
- Spider(单机爬虫)
- Feapder 的 Spider 类似 Scrapy,适合中小型项目
- Funspider 强依赖分布式架构,小项目过于复杂
- 内置下载器
- Feapder 内置多种下载器(requests、selenium、playwright)
- Funspider 需要用户自行实现下载逻辑
- 可以尝试将浏览器单独封装api ,每个tab 一个任务,节省资源。爬虫使用api 下载。
2.2 适用场景
Funspider 适合的场景:
- 长周期任务:持续运行数月甚至数年的数据采集
- 大规模爬取:数千万甚至数亿级别的数据量
- 分布式部署:需要多台机器协同工作
- 复杂调度:多层级的请求依赖关系(列表页→详情页→评论页)
不适合的场景:
- 一次性数据采集(推荐使用 Scrapy /feapder)
- 小规模项目(< 10万数据,推荐 Feapder AirSpider)
- 快速原型开发(推荐 Funboost 自带的 boost_spider)
boost_spider 示例(更简单):
三、框架现状与未来规划
3.1 当前状态
已实现的核心功能:
- 分布式请求调度(基于 Funboost)
- ItemBuffer 批量入库
- 多 Pipeline 支持(MySQL、MongoDB、Elasticsearch)
- 去重机制(内存 + Redis)
- 全链路追踪(Trace/Span)
- 失败数据恢复
- Web 管理界面(funboost自带了一个队列管理可以使用)
- 存在的问题:
- 代码质量
- 部分代码耦合度高,需要重构
- 注释和文档不够完善
3.2 TODO 清单
优先级 1:运维工具
1. Web 管理后台
2. 任务发布系统
3. 链路追踪可视化
优先级 2:代码重构
- 解耦核心模块
- 将 Worker、Engine、ItemBuffer 完全分离
- 统一接口规范,便于扩展
3.3 开源计划
开源时机:
完成以下条件后考虑开源:
- 代码质量达标
- 重构完成,模块清晰
- 文档完善
项目将在代码质量达标后开源,敬请期待!