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

news/2024/12/14 17:03:39 标签: 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:

python"># 使用 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

python">import scrapy
from scrapy_redis.spiders import RedisSpider

class QuotesSpider(RedisSpider):
    name = "quotes"
    # 从 Redis 获取初始 URL
    redis_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 数据存储:

python">import pymongo

class 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 中启用管道:

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

2. 数据清洗与分析

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

python">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 中添加:

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

3. 错误重试与代理

错误重试

配置重试机制:

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

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

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

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

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

python">import scrapy
from scrapy_redis.spiders import RedisSpider

class 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.niftyadmin.cn/n/5768314.html

相关文章

2024年陕西科技大学数据结构程序填空题+预测

递归实现插入排序 #include <stdio.h>void insertion_sort(int arr[], int n) {if (n > 1){insertion_sort(arr, n - 1);arr[0] arr[n];int i;for (i n - 1; i > 0; i--){if (arr[i] > arr[0]){arr[i 1] arr[i];}else{break;}}arr[i 1] arr[0];} }int m…

基于BERT的语义分析实现

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

go的math/rand随机数生成器

伪随机数生成器&#xff0c;默认情况下随机数种子是固定的&#xff0c; **注意&#xff1a;**固定的随机数种子每次生成的随机数都是相同的随机数序列 一、基础用法 math/rand 包提供了随机数生成的方法。常用的函数包括&#xff1a; rand.Int()&#xff1a;返回一个伪随机…

Secured Finance与GLIF建立战略合作关系,为Filecoin FVM赋能

“DeFi 巨头强强联合增强流动性质押&#xff0c;并开启全新收益机会。” Secured Finance 是一个专注于促进固定收益市场和跨链借贷服务的 DeFi 协议&#xff0c;允许用户在多个区块链生态系统之间高效、安全地执行借贷、债券交易和利率互换等金融操作。通过智能合约和去中心化…

Elasticsearch与NLP的深度融合:文本嵌入与向量搜索实战指南

Elasticsearch与NLP的深度融合:文本嵌入与向量搜索实战指南 引言 在当今信息爆炸的时代,如何从海量文本数据中快速准确地检索出相关信息,成为了一个迫切需要解决的问题。自然语言处理(NLP)技术的发展为这一挑战提供了新的解决方案。Elasticsearch,作为一个强大的搜索引…

open-instruct - 训练开放式指令跟随语言模型

文章目录 关于 open-instruct设置训练微调偏好调整RLVR 污染检查开发中仓库结构 致谢 关于 open-instruct github : https://github.com/allenai/open-instruct 这个仓库是我们对在公共数据集上对流行的预训练语言模型进行指令微调的开放努力。我们发布这个仓库&#xff0c;并…

三十:在Web当中什么样的响应才会被缓存?

Web缓存是提高网站性能、减轻服务器负担和优化用户体验的重要技术之一。然而&#xff0c;并非所有的HTTP响应都适合缓存。在Web开发中&#xff0c;理解什么样的响应应该被缓存&#xff0c;对于制定高效的缓存策略至关重要。本文将深入探讨哪些类型的响应适合缓存&#xff0c;以…

Pytorch使用手册-What is torch.nn really?(专题九)

我们建议将本教程作为 notebook 而不是脚本运行。要下载 notebook(.ipynb)文件,请点击页面顶部的链接。 PyTorch 提供了精心设计的模块和类,如 torch.nn、torch.optim、Dataset 和 DataLoader,帮助你创建和训练神经网络。为了充分利用这些工具的强大功能并根据你的问题进…