城市商户分布热力图分析
🔧 依赖检查(首次使用时自动执行)
本 Skill 需要通过高德地图 POI API 获取真实商户数据,且依赖 Python(requests 库)进行 API 调用和制图。
自动化检查步骤
步骤1:检查Python依赖
# 跨平台检查:requests / folium / openpyxl(缺失时安装)
python -c "import requests, folium, openpyxl" 2>/dev/null || pip install requests folium openpyxl
步骤2:检查高德地图 API Key
import os
key = os.environ.get('AMAP_KEY')
if not key:
print("""
❌ 未配置高德地图 API Key
请按以下步骤获取:
1. 打开 https://lbs.amap.com/(高德开放平台)
2. 注册并登录 → 控制台 → 应用管理
3. 创建新应用 → 添加 Key(选择 Web 服务)
4. 复制 Key 发送给我
5. 我会设置环境变量: AMAP_KEY=你的Key(Windows: `set AMAP_KEY=你的Key` / macOS/Linux: `export AMAP_KEY=你的Key`)
""")
依赖清单
| 依赖 | 类型 | 用途 |
|------|------|------|
| Python requests | 库 | 调用高德/腾讯/百度 POI API |
| Python folium | 库 | 生成交互式热力图 HTML(pip install folium) |
| Python openpyxl | 库 | Excel 输出(可选) |
| 高德地图 API Key | 免费注册 | 商户位置数据(必选) |
| 腾讯地图 API Key(可选) | 免费注册 | 多源补充数据 |
| 百度地图 AK(可选) | 免费注册 | 多源补充数据 |
⛔ 铁律:禁止虚拟数据 & 禁止幻觉
以下行为绝对禁止,无论在任何情况下:
- ❌ 禁止生成、捏造、模拟任何商户坐标数据或行业数据
- ❌ 禁止使用示例数据、测试数据、占位数据替代真实来源
- ❌ 禁止在 API 调用失败后继续制图
- ❌ 禁止在数据量为 0 时继续制图
- ❌ 禁止在代码中编写任何 fallback 虚拟坐标逻辑
- ❌ 禁止捏造行业规模、产值、企业数量等数据
- ❌ 禁止将其他城市的数据套用到当前城市
唯一合法的数据来源:
- 高德/腾讯/百度地图 POI API 返回的真实数据
- 经 AI Agent 实际网络搜索获取的公开信息(政府/媒体/协会公告)
数据为空或失败时的处理:
- 如实告知用户:获取到了多少条数据(包括 0 条)
- 说明失败原因(API Key 无效 / 关键词无匹配 / 网络问题)
- 停止制图,询问用户如何调整后重试
- 绝不自行补充数据继续执行
技能概述
本技能帮助用户生成城市特定商户/企业类型的分布热力图,并配套文字分析报告。
完整流程(6步,必须按顺序执行):
第0步(新增):行业分析 — AI 通过网络搜索定位城市重点行业
↓
第0.5步(新增):展示分析报告 → 用户确认 → 才进入下一步
↓
第1步:数据获取
├── 单源模式:fetch_poi.py(仅高德)
└── 多源模式:multi_poi.py → fetch_all_sources()(高德+腾讯+百度)
↓
第2步:展示数据概况,等待用户确认
↓
第3步:制作热力图(generate_heatmap.py)
↓
第4步:生成文字分析报告
API Key 配置
本 Skill 支持三家地图 API 数据源,设置环境变量即可激活:
# 高德地图(必选,主力数据源)— macOS/Linux:
export AMAP_KEY="你的高德开放平台 Key"
# Windows: set AMAP_KEY=你的高德开放平台 Key
# 腾讯地图(可选,补充数据源)— macOS/Linux:
export TENCENT_KEY="你的腾讯位置服务 Key"
# Windows: set TENCENT_KEY=你的腾讯位置服务 Key
# 百度地图(可选,补充数据源)— macOS/Linux:
export BAIDU_AK="你的百度地图 AK"
# Windows: set BAIDU_AK=你的百度地图 AK
Key 获取方式
| 平台 | 地址 | 免费配额 | 坐标系 | |------|------|:--:|------| | 高德 | console.amap.com | 5000次/天 | GCJ-02 | | 腾讯 | lbs.qq.com | 10000次/天 | GCJ-02 | | 百度 | lbsyun.baidu.com | 5000次/天 | BD-09(模块自动转换) |
多源覆盖提升:三源交叉可提升商户覆盖率至 90%+,各平台商户数据有约 15-20% 的差异。
第零步:行业分析(强制)— analyze_industry.py
这是新增的强制步骤。每次分析城市时都必须先执行此模块。
核心目标
在开始获取商户数据之前,先通过网络搜索分析目标城市的重点行业,确保:
- 分析的是本地真正的特色/优势行业,而非泛泛的"制造业"或"批发零售业"
- 关键词精确匹配行业实际命名特征,避免大量无关商户
- 用户全程知情并参与关键词配置决策
分析流程(4步)
Step 1 — 网络信息分析(AI Agent 执行)
使用 AI Agent 的 web search 工具,搜索以下方向:
目标城市 + 特色产业 / 支柱产业 / 产业集群
目标城市 + 政府工作报告 / 产业报告
目标城市 + 行业 + 年产值 / 企业数量 / 从业人员
从搜索结果中提取:
- 提及最多的行业关键词(按提及频率排序)
- 具体数据:年产值(亿)、企业数量(万家)、从业人员(万人)
- 来源:政府文件 / 媒体报道 / 行业协会公告(标注置信度)
重要:搜索结果中必须出现具体数字(XX亿/XX万家)才算有效数据。
Step 2 — 协会会员名单检索(AI Agent 执行)
搜索目标城市的相关行业协会/商会:
目标城市 + 行业协会名称(如:<城市>市<行业>行业协会)
目标城市 + 行业 + 商会 + 会员名单
协会会员名单用于提取真实命名特征词:
- 从会员名单中统计高频后缀词(如:XX珠宝 / XX玉器 / XX商行 / XX档口)
- 这些真实命名词比硬编码的"工厂/制造"更准确
如果本地没有协会,搜索省级或全国同类协会名单作为参考。
Step 3 — 平台数据补充(AI Agent 执行)
可选,用于补充量化数据:
目标城市 + 行业 + 1688供应商
目标城市 + 行业 + 企业注册数量(天眼查/企查查数据)
Step 4 — 综合研判 & 关键词配置生成(analyze_industry.py 执行)
将 Step 1-3 的搜索结果传入脚本,生成 TXT 报告:
import sys
sys.path.insert(0, 'scripts/')
from analyze_industry import run_analysis, save_keywords_config
# 构建搜索结果(由 AI Agent 实际搜索后填充)
step1 = {
"raw_results": [
{"title": "<搜索结果标题>", "summary": "<包含具体数据的摘要>", "query": "<搜索关键词>"},
...
]
}
step2 = {
"associations": [
{
"name": "<行业协会全称>",
"url": "<官网URL>",
"member_count": <会员数量>,
"member_names": ["<真实会员名>", "<真实会员名>", ...]
},
...
]
}
step3 = {
"data": [
{"industry": "<行业名>", "numbers": ["<量化数据>"], "source": "<来源>", "type": "media|1688|工商"}
]
}
judgment, report = run_analysis(
"<目标城市>",
step1_findings=step1,
step2_findings=step2,
step3_findings=step3,
user_industries=None # 或手动指定:["<行业A>", "<行业B>"]
)
# 保存关键词配置(确认前不执行取数)
config_path = save_keywords_config(judgment)
print(report) # 展示给用户
执行 analyze_industry.py
# 方式1:仅指定城市(由 AI Agent 通过环境变量传入搜索结果)
python scripts/analyze_industry.py <目标城市>
# 方式2:指定城市 + 行业列表(使用模板关键词,跳过搜索)
python scripts/analyze_industry.py <目标城市> <行业A>,<行业B>,<行业C>
快速简化路径(当网络搜索困难时)
当 Step 1-3 的网络搜索难以获取足够数据时,可以简化流程:
- AI Agent 通过对话向用户询问:"<目标城市>有哪些本地特色/优势行业?"
- 用户直接告诉 AI 要分析哪些行业
- AI 使用通用行业关键词模板生成配置
- 在分析报告中明确标注"置信度:低,建议结合实际调整关键词"
第零.五步:展示分析报告,等待用户确认
必须展示 TXT 报告,等待用户明确确认后才进入数据获取步骤。
报告结构:
======================================================================
<城市名> 行业分析报告
======================================================================
【数据来源置信度】
Step1 网络媒体分析: 高/中/低/无数据
Step2 行业协会检索: 高/中/低/无数据
Step3 平台数据补充: 高/中/低/无数据
【Step1:重点行业定位 — 网络信息分析】
>> <行业A>(媒体提及X次)
提取数据: <具体数字或"无具体产值数据">
数据来源: <来源列表>
>> <行业B>(媒体提及X次)
提取数据: <具体数字或"无具体产值数据">
数据来源: <来源列表>
【Step2:行业协会 — 会员名单 & 命名特征词】
>> <行业协会名>(会员数: XXXX)
名单样本: <样本名1>, <样本名2>, ...
命名高频后缀: <从真实名单提取的高频词>
【Step3:平台补充数据 — 1688/工商数据】
>> <行业>: <量化数据> | 来源: <来源>
【排除的行业分类】(范围过大,不宜作为分析维度)
X <被排除的分类> — 已排除
======================================================================
★★★ 搜索关键词配置(请重点审查这部分)★★★
======================================================================
>> <行业A>
搜索关键词: <关键词1> | <关键词2> | <关键词3> | ...
>> <行业B>
搜索关键词: <关键词1> | <关键词2> | ...
⚠️ 关键词说明:
- 以上关键词由分析流程自动生成,基于 Step1-Step3 数据
- 不含"批发"/"制造"/"工厂"等限定词(API通过type字段匹配更多商户)
- 如有不准确之处,请直接修改关键词列表
- 如需过滤特定类型商户(如排除零售专卖店),请在确认时说明
- 高德 POI type 字段可用于 post-processing 过滤,见下方参考
【POI type 过滤参考】(适用于用户确认时要求过滤的场景)
推荐保留: 家居建材市场、建材五金市场、厨卫市场、综合市场(各专业市场)、
公司、工厂
谨慎过滤: 专卖店(需结合商户名称判断是否相关)
建议排除: 便民商店/便利店、服装鞋帽皮具店(零售导向)
绝对排除: 水产海鲜市场、果品市场、农副产品市场(其他行业同名市场)
======================================================================
【分析局限性声明】
! <局限性说明>(如无协会名单、无平台数据等)
【下一步操作】
请您审查上述分析结果,如有以下情况请提出修改意见:
1. 行业遗漏:哪些重要行业未被列入?
2. 关键词偏差:哪些关键词可能引入不相关商户?
3. 数据错误:发现明显不符合实际的数据?
确认无误后,我将使用上述关键词配置开始获取高德商户数据并制图。
======================================================================
用户确认后,执行:
# 生成关键词配置文件(供 fetch_poi.py 使用)
config_path = save_keywords_config(judgment)
# config_path 指向 scripts/keywords_config_<目标城市>.json
第一步:理解用户需求(已整合入行业分析)
经过第零步行业分析后,用户需求已明确为:
- 目标城市(已确定)
- 分析行业 & 关键词配置(已生成并确认)
直接进入第二步数据获取。
第二步:调用高德 API 获取真实数据
必须执行 scripts/fetch_poi.py,不得跳过,不得替换。
用法
从 analyze_industry.py 确认的关键词配置读取:
import json
import sys
sys.path.insert(0, 'scripts/')
from fetch_poi import fetch_multi_category
# 读取行业分析确认的关键词配置
config_path = "scripts/keywords_config_<目标城市>.json"
with open(config_path, encoding="utf-8") as f:
config = json.load(f)
keywords_dict = config["keywords"] # {行业名: [关键词列表]}
city = config["city"]
# 执行数据获取
result = fetch_multi_category(city, keywords_dict, output_file="poi_data.json")
命令行直接调用
# 推荐:通过 analyze_industry 生成的关键词配置获取数据
# 先运行 analyze_industry.py 确认关键词,再运行 fetch_poi.py
python scripts/fetch_poi.py
# (默认使用文件顶部配置的关键词,支持交互式修改)
fetch_poi.py 关键参数
type 字段过滤(可选,推荐使用):
from fetch_poi import fetch_multi_category
# 推荐排除列表(过滤其他行业同名市场,减少噪音)
EXCLUDE_TYPES = [
"便民商店/便利店",
"服装鞋帽皮具店",
"水产海鲜市场",
"果品市场",
"农副产品市场",
]
result = fetch_multi_category(
city="<目标城市>",
keywords_dict={"<行业>": ["<关键词>"]},
output_file="poi_data.json",
exclude_type_keywords=EXCLUDE_TYPES
)
原理:高德 POI 的 type 字段包含三级分类(如 购物服务;家居建材市场;建材五金市场)。关键词搜索时,API 会匹配 name/address/type 多个字段,导致其他行业的同名市场(如"水果批发市场")被误匹配。过滤 type 字段中的无关分类,可以精准去噪,同时不影响真正的行业商户(因为真正的陶瓷商户 type 字段为"建材五金市场/厨卫市场",不在排除列表中)。
- 搜索策略:每个关键词单独分页搜索(禁止用
|合并,合并会严重截断数据) - QPS 配置:
REQUEST_INTERVAL = 0.15(150ms)+ QPS 限速自动重试 1 次(等 350ms) - API Key:通过环境变量
AMAP_KEY传入 - 数据输出:保存为
poi_data.json,数据为空时直接退出,不制图
⚠️ 本脚本不接受任何虚拟数据 fallback,数据为 0 时必须停止。
第二步(扩展):多源 POI 数据采集 — multi_poi.py
当配置了多个地图 API Key 时,推荐使用多源采集以提升商户覆盖率。
用法
import sys
sys.path.insert(0, 'scripts/')
from multi_poi import fetch_all_sources
# 多源采集(自动整合高德+腾讯+百度)
pois = fetch_all_sources(
city="深圳",
keywords=["酒店", "餐饮", "购物"],
max_per_category=2000
)
# 结果已自动去重合并,每个 POI 额外包含 'sources' 字段
# 如 ['amap', 'tencent'] 表示该商户被两家平台共同收录
命令行直接调用
cd scripts/
python multi_poi.py
# 使用文件底部的测试参数,结果保存为 poi_data_multi.json
去重策略
- 名称精确匹配:同名视为同一商户
- 坐标近邻匹配:距离 < 50m 且名称相似度 ≥ 50%
- 来源聚合:保留第一条数据,
sources字段记录所有覆盖平台
与 generate_heatmap.py 的兼容性
multi_poi.py 输出的 POI 格式兼容 generate_heatmap.py,直接替换 poi_data.json 即可:
python multi_poi.py
# 生成 poi_data_multi.json
# 重命名或复制为 poi_data.json 后运行 generate_heatmap.py
第三步:展示数据概况,等待用户确认
数据获取完成后,必须先展示结果,等用户确认后才开始制图:
📊 数据获取结果:
- 城市:<目标城市>
- 数据来源:高德地图 + 腾讯地图 + 百度地图 POI API(真实数据,多源合并)
- 获取时间:YYYY-MM-DD HH:MM
各分类数量:
- <行业A>:<数量> 条
- <行业B>:<数量> 条
- <行业C>:<数量> 条
主要分布区域(前3):<区县A> / <区县B> / <区县C>
是否继续制作热力图?
第四步:制作热力图
使用 scripts/generate_heatmap.py 制作热力图。
技术方案:
- 底图:高德地图瓦片(
webrd04.is.autonavi.com) - 地图中心:基于所有 POI 坐标均值计算
- 每个分类独立颜色,支持图层切换
python scripts/generate_heatmap.py poi_data.json <目标城市>
第五步:生成分析报告
基于真实数据输出分析报告,结构如下:
- 数据概况 - 来源、获取时间、各分类数量
- 分布特征 - 主要集聚区、核心商圈识别
- 热点解读 - 密度最高区域及可能原因
- 数据局限说明 - 高德 POI 数据覆盖的已知局限
常见问题排查
Q: API 返回数据量很少(几条或十几条),与实际不符?
A: 检查以下可能原因:
- 关键词太宽泛(如"店"、"公司")→ 换更具体的词
- 关键词与高德 POI 分类不匹配 → 参考
references/data-guide.md中的 typecode - 合并搜索使用
|分隔,多个词同时匹配(已禁用,强制单独搜索)
Q: 数据为 0 怎么办?
A: 如实告知用户,不生成热力图。帮助用户分析原因并调整关键词重试。
Q: 地图不显示?
A: 高德瓦片需要联网。检查网络是否正常,或临时换用 ArcGIS 作为备选底图。
相关文件
- 行业分析模块:
scripts/analyze_industry.py(新增) - 数据获取脚本:
scripts/fetch_poi.py - 热力图脚本:
scripts/generate_heatmap.py - 高德 POI 类型参考:
references/data-guide.md
Scan to join WeChat group