基于Scrapy-Redis的分布式景点数据爬取与热力图生成

本文涉及的产品
Elasticsearch Serverless检索通用型,资源抵扣包 100CU*H
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
实时数仓Hologres,5000CU*H 100GB 3个月
简介: 基于Scrapy-Redis的分布式景点数据爬取与热力图生成
  1. 引言
    在旅游行业和城市规划中,热门景点的数据分析具有重要意义。通过爬取景点数据并生成热力图,可以直观展示游客分布、热门区域及人流趋势,为商业决策、景区管理及智慧城市建设提供数据支持。
    然而,单机爬虫在面对大规模数据采集时可能面临效率瓶颈。Scrapy-Redis 作为Scrapy的分布式扩展,能够利用多台机器协同爬取数据,大幅提升采集速度和稳定性。本文将介绍如何基于Scrapy-Redis构建分布式爬虫,爬取热门景点数据,并使用 Folium 和 Heatmap.js 生成交互式热力图。
  2. 技术选型
    2.1 Scrapy-Redis 简介
    Scrapy-Redis 是 Scrapy 的分布式扩展,利用 Redis 作为任务队列和去重存储,实现多台爬虫节点的协同工作。其核心优势包括:
    ● 分布式调度:多个爬虫共享待爬队列,避免重复爬取。
    ● 断点续爬:Redis 持久化存储任务状态,即使爬虫中断也可恢复。
    ● 高效去重:基于 Redis 的集合(Set)或布隆过滤器(Bloom Filter)去重。
    2.2 数据存储与分析
    ● MongoDB:存储结构化景点数据(名称、评分、评论数、经纬度等)。
    ● Folium:Python 地理可视化库,基于 Leaflet.js 生成热力图。
    ● Heatmap.js:高性能的热力图渲染库,适合大数据量展示。
  3. 系统架构设计
    整个系统分为三个模块:
  4. 分布式爬虫(Scrapy-Redis):爬取景点数据并存储至 MongoDB。
  5. 数据预处理:清洗数据并提取经纬度信息。
  6. 热力图生成:使用 Folium + Heatmap.js 进行可视化。
  7. 实现步骤
    4.1 环境准备
    安装依赖:
    4.2构建 Scrapy-Redis 爬虫
    (1)创建 Scrapy 项目
    (2)配置 Scrapy-Redis
    修改 settings.py:
    ```# 启用 Scrapy-Redis 调度器
    SCHEDULER = "scrapy_redis.scheduler.Scheduler"
    DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"

Redis 连接配置

REDIS_URL = 'redis://localhost:6379/0'

数据存储到 MongoDB

ITEM_PIPELINES = {
'scrapy_redis.pipelines.RedisPipeline': 300,
'scenic_spider.pipelines.MongoPipeline': 400,
}

MONGO_URI = 'mongodb://localhost:27017'
MONGO_DB = 'scenic_data'

(3)编写爬虫逻辑
以美团景点为例(meituan_spider.py):
```import scrapy
from scenic_spider.items import ScenicItem
from urllib.parse import urlencode

# 代理配置
proxyHost = "www.16yun.cn"
proxyPort = "5445"
proxyUser = "16QMSOML"
proxyPass = "280651"

class MeituanSpider(scrapy.Spider):
    name = 'meituan_spider'
    redis_key = 'meituan:start_urls'  # Redis 初始任务队列

    # 自定义请求头(可选)
    custom_headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
    }

    def start_requests(self):
        # 从Redis获取初始URL时添加代理
        for url in self.get_start_urls():
            yield scrapy.Request(
                url=url,
                callback=self.parse,
                headers=self.custom_headers,
                meta={
                    'proxy': f'http://{proxyUser}:{proxyPass}@{proxyHost}:{proxyPort}'
                }
            )

    def parse(self, response):
        for scenic in response.css('.scenic-item'):
            item = ScenicItem()
            item['name'] = scenic.css('.title::text').get()
            item['rating'] = scenic.css('.score::text').get()
            item['reviews'] = scenic.css('.review-num::text').get()
            item['location'] = scenic.css('.address::text').get()
            yield item

        # 翻页逻辑(同样添加代理)
        next_page = response.css('.next-page::attr(href)').get()
        if next_page:
            yield scrapy.Request(
                url=next_page,
                callback=self.parse,
                headers=self.custom_headers,
                meta={
                    'proxy': f'http://{proxyUser}:{proxyPass}@{proxyHost}:{proxyPort}'
                }
            )

(4)数据存储(MongoDB Pipeline)
```import pymongo

class MongoPipeline:
def init(self, mongo_uri, mongo_db):
self.mongo_uri = mongo_uri
self.mongo_db = mongo_db

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

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

def close_spider(self, spider):
    self.client.close()

def process_item(self, item, spider):
    self.db['scenic_spots'].insert_one(dict(item))
    return item
4.3 分布式运行
启动多个爬虫节点(不同机器或进程):
Redis 会自动分配任务,确保数据不重复爬取。
4.4 数据预处理
从 MongoDB 提取数据并解析经纬度(使用 Geocoding API):
```import pandas as pd
from pymongo import MongoClient
import requests

client = MongoClient('mongodb://localhost:27017')
db = client['scenic_data']
collection = db['scenic_spots']

# 获取数据并转为 DataFrame
data = list(collection.find())
df = pd.DataFrame(data)

# 调用高德地图API获取经纬度
def get_geocode(address):
    url = f"https://restapi.amap.com/v3/geocode/geo?key=YOUR_AMAP_KEY&address={address}"
    res = requests.get(url).json()
    if res['status'] == '1' and res['geocodes']:
        lng, lat = res['geocodes'][0]['location'].split(',')
        return float(lng), float(lat)
    return None, None

df['lng'], df['lat'] = zip(*df['location'].apply(get_geocode))
df.to_csv('scenic_data.csv', index=False)

4.5 生成热力图
使用 Folium + Heatmap.js 渲染热力图:
```import folium
from folium.plugins import HeatMap

df = pd.read_csv('scenic_data.csv')
df = df.dropna(subset=['lat', 'lng'])

创建地图

m = folium.Map(location=[df['lat'].mean(), df['lng'].mean()], zoom_start=12)

生成热力图

heatdata = [[row['lat'], row['lng'], row['reviews']] for , row in df.iterrows()]
HeatMap(heat_data, radius=15).add_to(m)

保存为HTML

m.save('heatmap.html')
```
打开 heatmap.html 即可看到交互式热力图。

  1. 优化与扩展
    ● 动态数据更新:结合 Celery 定时爬取最新数据。
    ● 3D 热力图:使用 Kepler.gl 进行更高级的可视化。
    ● 反爬策略:使用代理池(如 Scrapy-ProxyPool)应对封禁。
  2. 结论
    本文介绍了基于 Scrapy-Redis 的分布式爬虫系统,从数据采集、存储到热力图生成的完整流程。该方案适用于旅游数据分析、城市规划等领域,并可扩展至其他垂直行业(如餐饮、房产)。未来可结合机器学习预测人流趋势,进一步提升商业价值。
相关文章
|
4天前
|
人工智能 安全 应用服务中间件
阿里巴巴 MCP 分布式落地实践:快速转换 HSF 到 MCP server
本文分享了阿里巴巴内部将大规模HSF服务快速转换为MCP Server的实践经验,通过Higress网关实现MCP协议卸载,无需修改代码即可接入MCP生态。文章分析了MCP生态面临的挑战,如协议快速迭代和SDK不稳定性,并详细介绍了操作步骤及组件功能。强调MCP虽非终极解决方案,但作为AI业务工程化的起点具有重要意义。最后总结指出,MCP只是AI原生应用发展的第一步,未来还有更多可能性值得探索。
149 29
|
3天前
|
数据采集 前端开发 JavaScript
Python爬虫如何应对网站的反爬加密策略?
Python爬虫如何应对网站的反爬加密策略?
|
8天前
|
机器学习/深度学习 人工智能 数据库
RAG 2.0 深入解读
本文从RAG 2.0 面临的主要挑战和部分关键技术来展开叙事,还包括了RAG的技术升级和关键技术等。
212 77
|
8天前
|
机器学习/深度学习 设计模式 人工智能
深度解析Agent实现,定制自己的Manus
文章结合了理论分析与实践案例,旨在帮助读者系统地认识AI Agent的核心要素、设计模式以及未来发展方向。
402 93
深度解析Agent实现,定制自己的Manus
|
8天前
|
人工智能 监控 JavaScript
MCP实战之Agent自主决策-让 AI玩转贪吃蛇
MCP服务器通过提供资源、工具、提示模板三大能力,推动AI实现多轮交互与实体操作。当前生态包含Manus、OpenManus等项目,阿里等企业积极合作,Cursor等工具已集成MCP市场。本文以贪吃蛇游戏为例,演示MCP Server实现流程:客户端连接服务端获取能力集,AI调用工具(如start_game、get_state)控制游戏,通过多轮交互实现动态操作,展示MCP在本地实践中的核心机制与挑战。
202 35
MCP实战之Agent自主决策-让 AI玩转贪吃蛇
|
15天前
|
人工智能 PyTorch 算法框架/工具
ACK AI Profiling:从黑箱到透明的问题剖析
本文从一个通用的客户问题出发,描述了一个问题如何从前置排查到使用AI Profiling进行详细的排查,最后到问题定位与解决、业务执行过程的分析,从而展现一个从黑箱到透明的精细化的剖析过程。
|
8天前
|
传感器 测试技术 开发工具
通义灵码添加上下文能力怎么用?一篇看懂
Qwen3系列混合推理模型已全面开源,其中Qwen3-235B-A22B在多项测试中表现卓越。通义灵码现已支持Qwen3,并上线编程智能体,具备自主决策与工具使用能力,可完成编码任务。开发者可通过多种方式添加上下文(如代码文件、图片、Git提交等),增强交互效果。体验地址:https://lingma.aliyun.com/download。
110 34
|
25天前
|
数据采集 存储 开发者
如何动态调整Python爬虫的Request请求延迟
如何动态调整Python爬虫的Request请求延迟
|
17天前
|
存储 人工智能 Prometheus
剑指大规模 AI 可观测,阿里云 Prometheus 2.0 应运而生
本文介绍了阿里云Prometheus 2.0方案,针对大规模AI系统的可观测性挑战进行全面升级。内容涵盖数据采集、存储、计算、查询及生态整合等维度。 Prometheus 2.0引入自研LoongCollector实现多模态数据采集,采用全新时序存储引擎提升性能,并支持RecordingRule与ScheduleSQL预聚合计算。查询阶段提供跨区域、跨账号的统一查询能力,结合PromQL与SPL语言增强分析功能。此外,该方案已成功应用于阿里云内部AI系统,如百炼、通义千问等大模型全链路监控。未来,阿里云将发布云监控2.0产品,进一步完善智能观测技术栈。
217 41
|
22天前
|
人工智能 运维 JavaScript
当AI学会了自我升级,天网还会远吗?
文章通过一个模拟侦探游戏的例子展示了AI如何通过“自我升级”和动态执行代码的能力来解决复杂问题。
182 33
当AI学会了自我升级,天网还会远吗?
OSZAR »