网易云课堂零基础: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​部署分布式爬虫集群

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

相关推荐
Rock_yzh4 小时前
AI学习日记——PyTorch深度学习快速入门:神经网络构建与训练实战
人工智能·pytorch·python·深度学习·神经网络·学习
中等生4 小时前
uv 完全指南:Python 包管理的现代化解决方案
python
hello kitty w4 小时前
Python学习(10) ----- Python的继承
开发语言·python·学习
懒羊羊不懒@4 小时前
Java一、二维数组
开发语言·python
中等生4 小时前
uvicorn 和 gunicorn
python
爱学习的小鱼gogo4 小时前
python 单词搜索(回溯-矩阵-字符串-中等)含源码(二十)
开发语言·数据结构·python·矩阵·字符串·回溯·递归栈
AI 嗯啦4 小时前
深度学习——Python 爬虫原理与实战:从入门到项目实践
爬虫·python·深度学习
MediaTea5 小时前
Python 第三方库:Word Cloud(词云图生成)
开发语言·python
B站_计算机毕业设计之家5 小时前
python股票交易数据管理系统 金融数据 分析可视化 Django框架 爬虫技术 大数据技术 Hadoop spark(源码)✅
大数据·hadoop·python·金融·spark·股票·推荐算法