Python爬虫(26)Python爬虫高阶:Scrapy+Selenium分布式动态爬虫架构实践

news2025/5/18 3:16:27

目录

      • 一、背景:动态爬虫的工程化挑战
      • 二、技术架构设计
        • 1. 系统架构图
        • 2. 核心组件交互
      • 三、环境准备与项目搭建
        • 1. 安装依赖库
        • 2. 项目结构
      • 四、核心模块实现
        • 1. Selenium集成到Scrapy(中间件开发)
        • 2. 分布式配置(settings.py)
      • 五、实战:电商平台全站爬虫开发
        • 1. 爬虫逻辑(product_spider.py)
        • 2. 动态分页处理
        • 3. 分布式任务分发
      • 六、高级优化策略
        • 1. 浏览器资源复用
        • 2. 智能请求调度
      • 七、总结
        • 1. 技术优势
        • 2. 性能指标对比
        • Python爬虫相关文章(推荐)

一、背景:动态爬虫的工程化挑战

在大规模数据采集场景中,爬虫开发者面临双重技术挑战:

  1. ‌动态交互难题‌:超过60%的现代网站采用JavaScript动态渲染内容(如无限滚动、异步分页、登录验证)
  2. ‌分布式扩展需求‌:单机爬虫难以应对百万级页面的抓取任务,需实现:
  • 任务队列共享
  • 节点状态协同
  • 数据去重聚合

‌技术方案选型‌:

  • ‌Scrapy‌:Python生态最成熟的异步爬虫框架,具备可扩展架构
  • ‌Selenium‌:浏览器自动化工具,破解动态交互的黄金钥匙
  • ‌Scrapy-Redis‌:基于Redis的分布式扩展组件,实现任务分发与状态同步

二、技术架构设计

1. 系统架构图
┌─────────────┐     ┌─────────────┐
│  Master节点 │◄───►│   RedisDB   │
└─────────────┘     └─────────────┘
        ▲                 ▲
        │                 │
┌───────┴───────┐ ┌───────┴───────┐
│  Worker节点1  │ │  Worker节点N  │
└───────────────┘ └───────────────┘

2. 核心组件交互
  • ‌Selenium‌:嵌入Scrapy下载器,执行页面渲染与交互
  • ‌Scrapy-Redis‌
    • RedisScheduler:中央任务调度
    • RedisPipeline:数据统一存储
    • BloomFilter:分布式去重

三、环境准备与项目搭建

1. 安装依赖库
pip install scrapy selenium scrapy-redis redis
# 下载对应版本的浏览器驱动(如chromedriver)

2. 项目结构
dynamic_spider/
├── scrapy.cfg
└── dynamic_spider/
    ├── middlewares.py    # 自定义中间件
    ├── settings.py       # 分布式配置
    ├── items.py          # 数据模型
    ├── pipelines.py      # Redis管道
    └── spiders/
        └── product_spider.py  # 爬虫逻辑

四、核心模块实现

1. Selenium集成到Scrapy(中间件开发)
# middlewares.py
from selenium import webdriver
from scrapy.http import HtmlResponse

class SeleniumMiddleware:
    def __init__(self):
        options = webdriver.ChromeOptions()
        options.add_argument("--headless")  # 无头模式
        self.driver = webdriver.Chrome(options=options)

    def process_request(self, request, spider):
        self.driver.get(request.url)
        # 执行动态交互(滚动/点击)
        self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")
        # 渲染完成后返回HTML
        return HtmlResponse(
            url=self.driver.current_url,
            body=self.driver.page_source,
            encoding='utf-8',
            request=request
        )

2. 分布式配置(settings.py)
# 启用Scrapy-Redis组件
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
ITEM_PIPELINES = {'scrapy_redis.pipelines.RedisPipeline': 300}

# Redis连接配置
REDIS_URL = 'redis://:password@127.0.0.1:6379/0'

五、实战:电商平台全站爬虫开发

1. 爬虫逻辑(product_spider.py)
import scrapy
from scrapy_redis.spiders import RedisSpider

class ProductSpider(RedisSpider):
    name = 'jd_product'
    redis_key = 'jd:start_urls'  # 从Redis读取种子URL

    def parse(self, response):
        # 提取商品列表
        products = response.css('.gl-item')
        for product in products:
            yield {
                'sku_id': product.attrib['data-sku'],
                'price': product.css('.p-price i::text').get(),
                'title': product.css('.p-name em::text').get()
            }

        # 模拟点击下一页(Selenium执行)
        next_page = response.css('a.pn-next::attr(href)').get()
        if next_page:
            yield scrapy.Request(url=response.urljoin(next_page))

2. 动态分页处理
# 在中间件中增加分页逻辑
def process_request(self, request, spider):
    self.driver.get(request.url)
    
    # 自动滚动加载(最多滚动5次)
    for _ in range(5):
        self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")
        time.sleep(1)
    
    # 点击"加载更多"按钮
    try:
        load_more = self.driver.find_element(By.CSS_SELECTOR, '.load-more')
        load_more.click()
        time.sleep(2)
    except NoSuchElementException:
        pass
    
    return HtmlResponse(...)

3. 分布式任务分发
# Master节点推送初始任务
redis-cli lpush jd:start_urls "https://www.jd.com/search?keyword=手机"

# 启动多个Worker节点
scrapy runspider product_spider.py

六、高级优化策略

1. 浏览器资源复用
# 使用浏览器池提升性能
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

class BrowserPool:
    def __init__(self, size=5):
        self.browsers = []
        for _ in range(size):
            options = Options()
            options.add_argument("--disable-gpu")
            driver = webdriver.Remote(
                command_executor='http://localhost:4444/wd/hub',
                options=options
            )
            self.browsers.append(driver)

2. 智能请求调度
# 根据页面类型动态选择渲染方式
def process_request(self, request, spider):
    if request.meta.get('need_js'):
        # 需要JS渲染的页面
        return self.selenium_render(request)
    else:
        # 静态页面直接使用Scrapy下载
        return None

七、总结

1. 技术优势
  1. ‌动态渲染全覆盖‌:通过Selenium处理任意复杂度交互
  2. ‌横向扩展能力‌:基于Redis轻松实现百节点级分布式集群
  3. ‌资源利用率提升‌:浏览器池技术降低85%的初始化开销
2. 性能指标对比
方案每秒请求数内存占用JS兼容性
纯Scrapy120+
Scrapy+Splash40-60
Scrapy+Selenium分布式80-100
Python爬虫相关文章(推荐)
Python爬虫介绍Python爬虫(1)Python爬虫:从原理到实战,一文掌握数据采集核心技术
HTTP协议解析Python爬虫(2)Python爬虫入门:从HTTP协议解析到豆瓣电影数据抓取实战
HTML核心技巧Python爬虫(3)HTML核心技巧:从零掌握class与id选择器,精准定位网页元素
CSS核心机制Python爬虫(4)CSS核心机制:全面解析选择器分类、用法与实战应用
静态页面抓取实战Python爬虫(5)静态页面抓取实战:requests库请求头配置与反反爬策略详解
静态页面解析实战Python爬虫(6)静态页面解析实战:BeautifulSoup与lxml(XPath)高效提取数据指南
Python数据存储实战 CSV文件Python爬虫(7)Python数据存储实战:CSV文件读写与复杂数据处理指南
Python数据存储实战 JSON文件Python爬虫(8)Python数据存储实战:JSON文件读写与复杂结构化数据处理指南
Python数据存储实战 MySQL数据库Python爬虫(9)Python数据存储实战:基于pymysql的MySQL数据库操作详解
Python数据存储实战 MongoDB数据库Python爬虫(10)Python数据存储实战:基于pymongo的MongoDB开发深度指南
Python数据存储实战 NoSQL数据库Python爬虫(11)Python数据存储实战:深入解析NoSQL数据库的核心应用与实战
Python爬虫数据存储必备技能:JSON Schema校验Python爬虫(12)Python爬虫数据存储必备技能:JSON Schema校验实战与数据质量守护
Python爬虫数据安全存储指南:AES加密Python爬虫(13)数据安全存储指南:AES加密实战与敏感数据防护策略
Python爬虫数据存储新范式:云原生NoSQL服务Python爬虫(14)Python爬虫数据存储新范式:云原生NoSQL服务实战与运维成本革命
Python爬虫数据存储新维度:AI驱动的数据库自治Python爬虫(15)Python爬虫数据存储新维度:AI驱动的数据库自治与智能优化实战
Python爬虫数据存储新维度:Redis Edge近端计算赋能Python爬虫(16)Python爬虫数据存储新维度:Redis Edge近端计算赋能实时数据处理革命
反爬攻防战:随机请求头实战指南Python爬虫(17)反爬攻防战:随机请求头实战指南(fake_useragent库深度解析)
反爬攻防战:动态IP池构建与代理IPPython爬虫(18)反爬攻防战:动态IP池构建与代理IP实战指南(突破95%反爬封禁率)
Python爬虫破局动态页面:全链路解析Python爬虫(19)Python爬虫破局动态页面:逆向工程与无头浏览器全链路解析(从原理到企业级实战)
Python爬虫数据存储技巧:二进制格式性能优化Python爬虫(20)Python爬虫数据存储技巧:二进制格式(Pickle/Parquet)性能优化实战
Python爬虫进阶:Selenium自动化处理动态页面Python爬虫(21)Python爬虫进阶:Selenium自动化处理动态页面实战解析

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2378182.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python 之类型注解

类型注解允许开发者显式地声明变量、函数参数和返回值的类型。但是加不加注解对于程序的运行没任何影响(是非强制的,且类型注解不影响运行时行为),属于 有了挺好,没有也行。但是大型项目按照规范添加注解的话&#xff…

【linux】Web服务—搭建nginx+ssl的加密认证web服务器

准备工作 步骤: 一、 新建存储网站数据文件的目录 二、创建一个该目录下的默认页面,index.html 三、使用算法进行加密 四、制作证书 五、编辑配置文件,可以选择修改主配置文件,但是不建议 原因如下: 自定义一个配置文…

基于HTTP头部字段的SQL注入:SQLi-labs第17-20关

前置知识:HTTP头部介绍 HTTP(超文本传输协议)头部(Headers)是客户端和服务器在通信时传递的元数据,用于控制请求和响应的行为、传递附加信息或定义内容类型等。它们分为请求头(Request Headers&…

实战解析MCP-使用本地的Qwen-2.5模型-AI协议的未来?

文章目录 目录 文章目录 前言 一、MCP是什么? 1.1MCP定义 1.2工作原理 二、为什么要MCP? 2.1 打破碎片化的困局 2.2 实时双向通信,提升交互效率 2.3 提高安全性与数据隐私保护 三、MCP 与 LangChain 的区别 3.1 目标定位不同 3.…

RabbitMQ高级篇-MQ的可靠性

目录 MQ的可靠性 1.如何设置数据持久化 1.1.交换机持久化 1.2.队列持久化 1.3.消息持久化 2.消息持久化 队列持久化: 消息持久化: 3.非消息持久化 非持久化队列: 非持久化消息: 4.消息的存储机制 4.1持久化消息&…

fpga系列 HDL : Microchip FPGA开发软件 Libero Soc 项目仿真示例

新建项目 项目初始界面中创建或导入设计文件: 新建HDL文件 module test (input [3:0] a,input [3:0] b,output reg [3:0] sum,output reg carry_out );always (*) begin{carry_out, sum} a b; endendmodule点击此按钮可进行项目信息的重新…

DeepSearch:WebThinker开启AI搜索研究新纪元!

1,项目简介 WebThinker 是一个深度研究智能体,使 LRMs 能够在推理过程中自主搜索网络、导航网页,并撰写研究报告。这种技术的目标是革命性的:让用户通过简单的查询就能在互联网的海量信息中进行深度搜索、挖掘和整合,从…

springCloud/Alibaba常用中间件之Setinel实现熔断降级

文章目录 SpringCloud Alibaba:依赖版本补充Sentinel:1、下载-运行&#xff1a;Sentinel(1.8.6)下载sentinel&#xff1a;运行&#xff1a;Sentinel <br> 2、流控规则① 公共的测试代码以及需要使用的测试Jmeter①、流控模式1. 直接:2. 并联:3. 链路: ②、流控效果1. 快速…

Deeper and Wider Siamese Networks for Real-Time Visual Tracking

现象&#xff1a; the backbone networks used in Siamese trackers are relatively shallow, such as AlexNet , which does not fully take advantage of the capability of modern deep neural networks. direct replacement of backbones with existing powerful archite…

黑马程序员C++2024版笔记 第0章 C++入门

1.C代码的基础结构 以hello_world代码为例&#xff1a; 预处理指令 #include<iostream> using namespace std; 代码前2行是预处理指令&#xff0c;即代码编译前的准备工作。&#xff08;编译是将源代码转化为可执行程序.exe文件的过程&#xff09; 主函数 主函数是…

foxmail - foxmail 启用超大附件提示密码与帐号不匹配

foxmail 启用超大附件提示密码与帐号不匹配 问题描述 在 foxmail 客户端中&#xff0c;启用超大附件功能&#xff0c;输入了正确的账号&#xff08;邮箱&#xff09;与密码&#xff0c;但是提示密码与帐号不匹配 处理策略 找到 foxmail 客户端目录/Global 目录下的 domain.i…

Crowdfund Insider聚焦:CertiK联创顾荣辉解析Web3.0创新与安全平衡之术

近日&#xff0c;权威金融科技媒体Crowdfund Insider发布报道&#xff0c;聚焦CertiK联合创始人兼CEO顾荣辉教授在Unchained Summit的主题演讲。报道指出&#xff0c;顾教授的观点揭示了Web3.0生态当前面临的挑战&#xff0c;以及合规与技术在推动行业可持续发展中的关键作用。…

PowerBI链接EXCEL实现自动化报表

PowerBI链接EXCEL实现自动化报表 曾经我将工作中一天的工作缩短至2个小时&#xff0c;其中最关键的一步就是使用PowerBI链接Excel做成一个自动化报表&#xff0c;PowerBI更新源数据&#xff0c;Excel更新报表并且保留报表格式。 以制作一个超市销售报表为例&#xff0c;简单叙…

腾讯云MCP数据智能处理:简化数据探索与分析的全流程指南

引言 在当今数据驱动的商业环境中&#xff0c;企业面临着海量数据处理和分析的挑战。腾讯云MCP(Managed Cloud Platform)提供的数据智能处理解决方案&#xff0c;为数据科学家和分析师提供了强大的工具集&#xff0c;能够显著简化数据探索、分析流程&#xff0c;并增强数据科学…

Android framework 中间件开发(一)

在Android开发中,经常会调用到一些系统服务,这些系统服务简化了上层应用的开发,这便是中间件的作用,中间件是介于系统和应用之间的桥梁,将复杂的底层逻辑进行一层封装,供上层APP直接调用,或者将一些APP没有权限一些操作放到中间件里面来实施. 假设一个需求,通过中间件调节系统亮…

MATLAB中的概率分布生成:从理论到实践

MATLAB中的概率分布生成&#xff1a;从理论到实践 引言 MATLAB作为一款强大的科学计算软件&#xff0c;在统计分析、数据模拟和概率建模方面提供了丰富的功能。本文将介绍如何使用MATLAB生成各种常见的概率分布&#xff0c;包括均匀分布、正态分布、泊松分布等&#xff0c;并…

C# 面向对象 构造函数带参无参细节解析

继承类构造时会先调用基类构造函数&#xff0c;不显式调用基类构造函数时&#xff0c;默认调用基类无参构造函数&#xff0c;但如果基类没有写无参构造函数&#xff0c;会无法调用从而报错&#xff1b;此时&#xff0c;要么显式的调用基类构造函数&#xff0c;并按其格式带上参…

在 C# 中将 DataGridView 数据导出为 CSV

在此代码示例中&#xff0c;我们将学习如何使用 C# 代码将 DataGridView 数据导出到 CSV 文件并将其保存在文件夹中。 在这个程序中&#xff0c;首先&#xff0c;我们必须连接到数据库并从中获取数据。然后&#xff0c;我们将在数据网格视图中显示该数据&#xff0c;…

MySQL中表的增删改查(CRUD)

一.在表中增加数据&#xff08;Create&#xff09; INSERT [INTO] TB_NAME [(COLUMN1,COLUMN2,...)] VALUES (value_list1),(value_list2),...;into可以省略可仅选择部分列选择插入&#xff0c;column即选择的列&#xff0c; 如图例可以选择仅在valuelist中插入age和id如果不指…

项目思维vs产品思维

大家好&#xff0c;我是大明同学。 这期内容&#xff0c;我们来聊一下项目思维和产品思维的区别。 项目是实施关键&#xff0c;力求每一步都精准到位&#xff1b;产品则是战略导向&#xff0c;确保所选之路正确无误。若缺乏优异成果&#xff0c;即便按时完成&#xff0c;也只…