网易云课堂零基础:21天搞定Python分布爬虫

​Python分布式爬虫完全教程:从基础原理到Scrapy-Redis实战(附完整源码)​

​1. 为什么需要分布式爬虫?​

作为爬虫工程师,我们经常面临这样的挑战:

  • ​单机爬虫的瓶颈​:当需要爬取百万级页面时,单台机器的CPU、内存和网络带宽成为限制
  • ​反爬机制​:目标网站可能对单一IP的频繁请求进行封禁
  • ​效率需求​:希望爬虫能够24小时不间断工作,充分利用多台机器的资源

​分布式爬虫解决方案​​:

通过多台机器协同工作,将爬取任务分散到不同节点,实现​​任务分配、数据存储、结果汇总​​的分布式处理


​2. 分布式爬虫核心原理​

​(1) 基本架构​

scss 复制代码
[主节点] (任务调度)
  │
  ├──[爬虫节点1] → 爬取URL1 → 存储数据
  ├──[爬虫节点2] → 爬取URL2 → 存储数据
  └──[爬虫节点N] → 爬取URLN → 存储数据

​关键组件​​:

  • ​任务队列​:存储待爬取的URL(Redis/MQ)
  • ​去重集合​:记录已爬URL避免重复(Redis Set/Bloom Filter)
  • ​结果存储​:MongoDB/MySQL存储爬取数据

​(2) 分布式核心技术点​

ini 复制代码
# 伪代码展示核心逻辑
while True:
    # 1. 从分布式队列获取任务
    url = redis.lpop('task_queue')  
    
    # 2. 检查是否已爬取(去重)
    if not redis.sismember('visited_urls', url):
        # 3. 执行爬取
        html = download(url)
        data = parse(html)
        
        # 4. 存储结果
        mongo.insert(data)
        redis.sadd('visited_urls', url)  # 标记已爬

​3. 实战:Scrapy-Redis分布式爬虫​

​(1) 环境准备​

复制代码
pip install scrapy scrapy-redis redis pymongo

​(2) 项目结构​

bash 复制代码
distributed_spider/
├── spiders/
│   └── example_spider.py  # 爬虫核心逻辑
├── settings.py           # 分布式配置
└── requirements.txt

​(3) 核心配置(settings.py)​

ini 复制代码
# 启用Scrapy-Redis调度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"

# 确保所有爬虫共享相同的去重过滤
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"

# Redis连接配置
REDIS_HOST = 'your_redis_server'  # 可以是云Redis或本地
REDIS_PORT = 6379
REDIS_PASSWORD = 'your_password'  # 如果有密码

# 保持爬取状态(可选)
SCHEDULER_PERSIST = True

​(4) 爬虫实现(example_spider.py)​

python 复制代码
import scrapy
from scrapy_redis.spiders import RedisSpider

class ExampleSpider(RedisSpider):
    name = 'example'
    # 注意:这里不定义start_urls,而是从Redis获取
    redis_key = 'example:start_urls'  # Redis中的起始URL键名

    def parse(self, response):
        # 示例:提取页面标题和链接
        yield {
            'url': response.url,
            'title': response.css('title::text').get(),
            'content_length': len(response.text)
        }
        
        # 提取新链接并加入队列(分布式自动处理)
        for link in response.css('a::attr(href)').getall():
            yield response.follow(link, callback=self.parse)

​4. 分布式部署实战​

​(1) 启动Redis服务​

bash 复制代码
# 本地启动(测试用)
redis-server

# 或使用云Redis(如阿里云Redis)

​(2) 添加初始任务​

java 复制代码
import redis

r = redis.Redis(host='localhost', port=6379)
r.lpush('example:start_urls', 'https://example.com')  # 添加种子URL

​(3) 启动多个爬虫节点​

bash 复制代码
# 在多台机器/终端执行(相同代码)
scrapy crawl example

​关键说明​​:

  • 所有节点共享同一个Redis任务队列
  • 每个URL只会被一个节点爬取(自动去重)
  • 爬取结果可以统一存储到MongoDB

​5. 进阶优化技巧​

​(1) 动态负载均衡​

ini 复制代码
# 在settings.py中调整并发参数
CONCURRENT_REQUESTS = 32  # 每个节点并发数
DOWNLOAD_DELAY = 0.5      # 下载延迟(秒)

# 按域名限制并发
AUTOTHROTTLE_ENABLED = True

​(2) 断点续爬​

shell 复制代码
# SCHEDULER_PERSIST = True  # 已在配置中启用
# 重启爬虫时会自动继续未完成的任务

​(3) 结果存储优化(MongoDB示例)​

python 复制代码
# pipelines.py
import pymongo

class MongoPipeline:
    def __init__(self, mongo_uri):
        self.mongo_uri = mongo_uri

    @classmethod
    def from_crawler(cls, crawler):
        return cls(
            mongo_uri=crawler.settings.get('MONGO_URI')
        )

    def open_spider(self, spider):
        self.client = pymongo.MongoClient(self.mongo_uri)
        self.db = self.client['crawler_db']

    def process_item(self, item, spider):
        self.db['pages'].insert_one(dict(item))
        return item

​6. 完整项目源码结构​

bash 复制代码
distributed_spider/
├── scrapy.cfg
├── distributed_spider/
│   ├── __init__.py
│   ├── items.py          # 数据结构定义
│   ├── middlewares.py    # 中间件配置
│   ├── pipelines.py      # 数据存储管道
│   ├── settings.py       # 核心配置
│   └── spiders/
│       ├── __init__.py
│       └── example_spider.py  # 主爬虫逻辑
└── requirements.txt

​requirements.txt内容​​:

ini 复制代码
scrapy==2.11.0
scrapy-redis==0.7.2
redis==4.5.5
pymongo==4.3.3

​7. 常见问题解决方案​

​(1) 反爬应对策略​

ruby 复制代码
# 在middlewares.py中添加
class RandomUserAgentMiddleware:
    def process_request(self, request, spider):
        request.headers['User-Agent'] = random.choice(USER_AGENTS)

​(2) 分布式监控​

bash 复制代码
# 使用Redis CLI监控任务队列
redis-cli llen example:start_urls  # 查看剩余任务数
redis-cli scard example:dupefilter # 查看过滤的URL数

​(3) 性能调优建议​

  1. 根据目标网站响应速度调整DOWNLOAD_DELAY
  2. 对重要域名设置单独的并发限制
  3. 使用Redis集群提高任务队列可靠性

​8. 总结:分布式爬虫开发要点​

核心要素 实现方案 注意事项
​任务分发​ Redis队列 确保所有节点连接同一Redis
​去重控制​ Redis Set/Bloom Filter 大规模爬取考虑Bloom Filter
​容错处理​ 持久化调度状态 SCHEDULER_PERSIST=True
​扩展性​ 动态添加爬虫节点 无状态设计,随时扩容

​下一步学习建议​​:

  1. 尝试结合​Selenium​处理JavaScript渲染页面
  2. 研究​Kafka​替代Redis作为任务队列
  3. 学习​Docker​部署分布式爬虫集群

通过这套方案,你可以轻松构建一个​​每小时处理数万页面​​的分布式爬虫系统! 🚀

相关推荐
生信大表哥4 小时前
单细胞测序分析(五)降维聚类&数据整合
linux·python·聚类·数信院生信服务器
seeyoutlb5 小时前
微服务全局日志处理
java·python·微服务
ada7_5 小时前
LeetCode(python)——148.排序链表
python·算法·leetcode·链表
岁月宁静6 小时前
LangChain + LangGraph 实战:构建生产级多模态 WorkflowAgent 的完整指南
人工智能·python·agent
第二只羽毛7 小时前
主题爬虫采集主题新闻信息
大数据·爬虫·python·网络爬虫
plmm烟酒僧7 小时前
TensorRT 推理 YOLO Demo 分享 (Python)
开发语言·python·yolo·tensorrt·runtime·推理
天才测试猿7 小时前
Postman中变量的使用详解
自动化测试·软件测试·python·测试工具·职场和发展·接口测试·postman
帕巴啦7 小时前
Arcgis计算面要素的面积、周长、宽度、长度及最大直径
python·arcgis
AI小云7 小时前
【数据操作与可视化】Matplotlib绘图-生成其他图表类型
开发语言·python·matplotlib
MediaTea7 小时前
Python 第三方库:plotnine(类 ggplot 的 Python 数据可视化库)
开发语言·python·信息可视化