Python 网络爬虫高级教程:分布式爬取与大规模数据处理

经过基础爬虫和进阶爬虫的学习,我们已经掌握了爬虫的基本原理、动态内容处理及反爬机制的应对。然而,当我们面对海量数据或需要高效爬取多个站点时,分布式爬虫和数据存储、处理能力就显得尤为重要。本篇博客将带你迈向网络爬虫的高级阶段,学习分布式爬取、大规模数据处理以及性能优化。


一、分布式爬虫的概念

1. 什么是分布式爬虫?

分布式爬虫是指通过多个节点协作完成大规模网页爬取任务的爬虫架构。它能有效解决以下问题:

  • 单台机器性能瓶颈(CPU、内存、网络带宽)。
  • 爬取任务量大时的效率问题。
  • 减少单个 IP 被封禁的风险。

2. 分布式爬虫的架构

分布式爬虫通常由以下部分组成:

  1. 任务队列:存储待爬取的 URL 列表。
  2. 多个爬虫节点:从任务队列中取出任务并执行爬取。
  3. 数据存储:将爬取的数据存储到数据库或文件中。
  4. 任务调度器:控制任务的分发和爬取状态。

二、使用 Scrapy 实现分布式爬虫

1. 安装 Scrapy 和 Scrapy-Redis

Scrapy 是一个强大的 Python 爬虫框架,支持分布式爬取。我们还需要 Scrapy-Redis 来实现任务队列的共享。

安装依赖库:

pip install scrapy scrapy-redis

2. Scrapy 项目结构

使用 Scrapy 创建一个新项目:

scrapy startproject distributed_crawler

项目结构:

distributed_crawler/
├── distributed_crawler/
│   ├── spiders/            # 爬虫文件目录
│   ├── __init__.py
│   ├── items.py            # 定义数据结构
│   ├── middlewares.py      # 爬虫中间件
│   ├── pipelines.py        # 数据存储管道
│   └── settings.py         # 项目配置
├── scrapy.cfg

3. 配置分布式功能

settings.py 中,配置 Scrapy-Redis:

# 使用 Scrapy-Redis 的调度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"# 使用 Scrapy-Redis 的去重类
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"# 配置 Redis 地址
REDIS_HOST = 'localhost'
REDIS_PORT = 6379# 是否持久化队列,True 表示爬取完成后保留任务队列
SCHEDULER_PERSIST = True

4. 编写爬虫

spiders 目录下创建爬虫文件 quotes_spider.py

import scrapy
from scrapy_redis.spiders import RedisSpiderclass QuotesSpider(RedisSpider):name = "quotes"# 从 Redis 获取初始 URLredis_key = "quotes:start_urls"def parse(self, response):for quote in response.css("div.quote"):yield {"text": quote.css("span.text::text").get(),"author": quote.css("small.author::text").get(),}# 爬取下一页next_page = response.css("li.next a::attr(href)").get()if next_page:yield response.follow(next_page, self.parse)

5. 配置 Redis 并运行

启动 Redis

确保 Redis 服务正在运行:

redis-server
添加起始 URL

将 URL 推送到 Redis:

redis-cli
> lpush quotes:start_urls http://quotes.toscrape.com
启动爬虫

运行爬虫:

scrapy crawl quotes

此时,多个爬虫节点可以通过共享 Redis 队列协作完成任务。


三、大规模数据处理与存储

分布式爬虫会产生大量数据,如何存储和处理这些数据是另一个重要问题。


1. 数据库存储

使用 MongoDB 存储数据

pipelines.py 中配置 MongoDB 数据存储:

import pymongoclass MongoPipeline:def open_spider(self, spider):self.client = pymongo.MongoClient("localhost", 27017)self.db = self.client["quotes_db"]def close_spider(self, spider):self.client.close()def process_item(self, item, spider):self.db["quotes"].insert_one(dict(item))return item

settings.py 中启用管道:

ITEM_PIPELINES = {'distributed_crawler.pipelines.MongoPipeline': 300,
}

2. 数据清洗与分析

爬取数据后,可以使用 Pandas 进行数据清洗和分析:

import pandas as pd# 读取数据
data = pd.read_json("quotes.json")# 数据清洗
data = data.drop_duplicates()  # 去重# 数据分析
author_counts = data["author"].value_counts()
print(author_counts)

3. 分布式存储与处理(可选)

对于更大规模的数据,可以使用分布式存储和处理工具:

  • 存储:使用 Hadoop HDFS 或 Amazon S3。
  • 处理:使用 Apache Spark 或 Hive。

四、性能优化


1. 增加爬虫节点

在分布式架构中,可以通过增加爬虫节点数量来提升效率。

配置多个节点时,只需共享相同的 Redis 配置,每个节点运行:

scrapy crawl quotes

2. 限制并发数

为了避免服务器封禁,可以限制爬取速度和并发数:

settings.py 中添加:

DOWNLOAD_DELAY = 1  # 请求间隔时间,单位秒
CONCURRENT_REQUESTS = 8  # 最大并发请求数

3. 错误重试与代理

错误重试

配置重试机制:

RETRY_ENABLED = True
RETRY_TIMES = 3  # 重试次数
使用代理池

通过免费或付费代理池切换 IP,防止被封禁。

DOWNLOADER_MIDDLEWARES = {'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 110,'distributed_crawler.middlewares.ProxyMiddleware': 100,
}

五、实战案例:分布式新闻爬虫

以下是一个分布式爬虫抓取新闻网站标题和链接的示例。

import scrapy
from scrapy_redis.spiders import RedisSpiderclass NewsSpider(RedisSpider):name = "news"redis_key = "news:start_urls"def parse(self, response):for article in response.css("div.article"):yield {"title": article.css("h2.title::text").get(),"link": article.css("a::attr(href)").get(),}# 爬取下一页next_page = response.css("a.next::attr(href)").get()if next_page:yield response.follow(next_page, self.parse)

六、总结

通过本篇博客,你学习了:

  1. 使用 Scrapy 和 Scrapy-Redis 实现分布式爬虫。
  2. 将爬取数据存储到 MongoDB,并进行数据清洗和分析。
  3. 优化爬虫性能的方法,包括并发限制和代理池。

下一步,你可以尝试构建一个分布式爬虫项目,如爬取多个电商网站的商品价格,并整合大规模数据分析。分布式爬虫不仅提升效率,还能应对复杂的网络爬取任务。继续深挖,你将能驾驭更多高级应用场景!

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

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

相关文章

Loadsh源码分析-every,some,size,includes

collection相关的函数, collection指的是一组用于处理集合(如数组或对象)的工具函数。 lodash源码研读之every,some,size,includes 一、源码地址 GitHub 地址: GitHub - lodash/lodash: A modern JavaScript utility library delivering mo…

力扣81:搜索旋转排序数组II

已知存在一个按非降序排列的整数数组 nums &#xff0c;数组中的值不必互不相同。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转 &#xff0c;使数组变为 [nums[k], nums[k1], ..., nums[n-1], n…

性能监控系统Prometheus、Node-exporter与Grafana部署详解搭建

简介 Prometheus、node-exporter整合到Grafana三者结合,构建了一个强大的监控体系,专门用于 Linux 主机和容器的监控。这个体系能够实时收集、分析和可视化各种系统指标。Prometheus是这个监控体系的核心,负责收集和存储来自各个目标的指标数据Node Exporter是一个部署在被监…

数据并行、模型并行与张量并行:深度学习中的并行计算策略(中英双语)

中文版 数据并行、模型并行与张量并行&#xff1a;深度学习中的并行计算策略 随着深度学习模型的不断增大&#xff0c;单个计算节点&#xff08;例如单个 GPU&#xff09;的计算和内存能力逐渐成为了限制训练效率和模型规模的瓶颈。为了应对这些挑战&#xff0c;深度学习社区…

Android so库的编译

在没弄明白so库编译的关系前,直接看网上博主的博文,常常会觉得云里雾里的,为什么一会儿通过Android工程cmake编译,一会儿又通过NDK命令去编译。两者编译的so库有什么区别? android版第三方库编译总体思路: 对于新手小白来说搞明白上面的总体思路图很有必…

Java函数式编程+Lambda表达式

文章目录 函数式编程介绍纯函数Lambda表达式基础Lambda的引入传统方法1. 顶层类2. 内部类3. 匿名类 Lambda 函数式接口&#xff08;Functional Interface&#xff09;1. **函数式接口的定义**示例&#xff1a; 2. **函数式接口与Lambda表达式的关系**关联逻辑&#xff1a;示例&…

Linux操作系统2-进程控制3(进程替换,exec相关函数和系统调用)

上篇文章&#xff1a;Linux操作系统2-进程控制2(进程等待&#xff0c;waitpid系统调用&#xff0c;阻塞与非阻塞等待)-CSDN博客 本篇代码Gitee仓库&#xff1a;Linux操作系统-进程的程序替换学习 d0f7bb4 橘子真甜/linux学习 - Gitee.com 本篇重点&#xff1a;进程替换 目录 …

文件上传漏洞:你的网站安全吗?

文章目录 文件上传漏洞攻击方式&#xff1a;0x01绕过前端限制0x02黑名单绕过1.特殊解析后缀绕过2..htaccess解析绕过3.大小写绕过4.点绕过5.空格绕过6.::$DATA绕过7.配合中间件解析漏洞8.双后缀名绕过9.短标签绕过 0x03白名单绕过1.MIME绕过(Content-Type绕过)2.%00截断3.0x00截…

设计模式-适配器模式-注册器模式

设计模式-适配器模式-注册器模式 适配器模式 如果开发一个搜索中台&#xff0c;需要适配或接入不同的数据源&#xff0c;可能提供的方法参数和平台调用的方法参数不一致&#xff0c;可以使用适配器模式 适配器模式通过封装对象将复杂的转换过程隐藏于幕后。 被封装的对象甚至…

springboot341+vue校园求职招聘系统设计和实现pf(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 校园求职招聘系统设计与实现 摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;…

基于java web的网上书店系统设计

摘 要 随着互联网的越发普及&#xff0c;网上购物成为了当下流行的热门行为。网络上开店创业有许多的优势&#xff1a;投入少&#xff0c;启动 资金低&#xff0c;交易便捷。网上书店与传统的线下书店比起来优势巨大&#xff0c;网上书店的经营方式和销售渠道是不同与线下书 店…

【分布式】分布式事务

目录 1、事务的发展 2、本地事务 &#xff08;1&#xff09;如何保障原子性和持久性&#xff1f; &#xff08;2&#xff09;如何保障隔离性&#xff1f; 2、全局事务 &#xff08;1&#xff09;XA事务的两段式提交 &#xff08;2&#xff09;XA事务的三段式提交…

课程学习 (Curriculum Learning) 介绍及其在 DeepSpeed 框架中的应用:中英双语

中文版 课程学习 (Curriculum Learning) 介绍及其在 DeepSpeed 框架中的应用 1. 课程学习的概念 课程学习&#xff08;Curriculum Learning&#xff09;是机器学习中的一种训练策略&#xff0c;灵感来源于人类学习的过程——从简单到复杂逐步掌握知识。具体来说&#xff0c;…

Java设计模式——职责链模式:解锁高效灵活的请求处理之道

嘿&#xff0c;各位 Java 编程大神和爱好者们&#xff01;今天咱们要一同深入探索一种超厉害的设计模式——职责链模式。它就像一条神奇的“处理链”&#xff0c;能让请求在多个对象之间有条不紊地传递&#xff0c;直到找到最合适的“处理者”。准备好跟我一起揭开它神秘的面纱…

团队自创【国王的魔镜-2】

国王的魔镜-2 题目描述 国王有一个魔镜&#xff0c;可以把任何接触镜面的东西变成原来的两倍——只是&#xff0c;因为是镜子嘛&#xff0c;增加的那部分是反的。比如一条项链&#xff0c;我们用AB来表示&#xff0c;不同的字母表示不同颜色的珍珠。如果把B端接触镜面的话&am…

Android 设备使用 Wireshark 工具进行网络抓包

背景 电脑和手机连接同一网络&#xff0c;想使用wireshark抓包工具抓取Android手机网络日志&#xff0c;有以下两种连接方法&#xff1a; Wi-Fi 网络抓包。USB 网络共享抓包。需要USB 数据线将手机连接到电脑&#xff0c;并在开发者模式中启用 USB 网络共享。 查看设备连接信…

redis大key和热key

redis中大key、热key 什么是大key大key可能产生的原因大key可能会造成什么影响如何检测大key如何优化删除大key时可能的问题删除大key的策略 热key热key可能导致的问题解决热key的方法 什么是大key 大key通常是指占用内存空间过大或包含大量元素的键值对。 数据量大&#xff…

SpringBoot源码-spring boot启动入口ruan方法主线分析(二)

12.刷新前操作 // 刷新前操作prepareContext(context, environment, listeners, applicationArguments, printedBanner);进入prepareContext private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,SpringApplicationRun…

macOS 版本对应的 Xcode 版本,以及 Xcode 历史版本下载

注&#xff1a;当前页面的所有Xcode下载链接均为苹果官方下载链接 &#xff0c;点击将直接转至苹果官网下载。 Xcode版本Xcode发布时间对应macOS版本macOS SDKsiOS SDKswatchOS SDKstvOS SDKs下载Xcode发布日志Xcode 15.413 May 2024macOS 14.014.5 (23F73)17.5 (21F77)10.5 (…

深入解析分布式遗传算法及其Python实现

目录 深入解析分布式遗传算法及其Python实现目录第一部分:分布式遗传算法的背景与原理1.1 遗传算法概述1.2 分布式遗传算法的引入1.3 分布式遗传算法的优点与挑战优点:挑战:第二部分:分布式遗传算法的通用Python实现2.1 基本组件的实现第三部分:案例1 - 基于多种交叉与变异…