一、案例背景与采集目标
打开本地生活平台,搜「火锅」「理发」「汽车保养」,出来的是一屏一屏的商户卡片:店名、评分、评论数、人均消费、地址、几个标签。这些信息凑在一起,就是一份现成的商业地理样本——哪条街餐饮最密、哪个商圈的客单价最高,都能算出来。
但这一篇我们不教你去爬点评类页面(它们反爬很强、条款也严),而是走最合规的那条路:用官方开放接口。示范站点是 高德地图开放平台,网址 https://lbs.amap.com/api/webservice/guide/api-advanced/search。它的「周边搜索」接口,你只要申请一个 key,就能按「中心点 + 半径 + 关键词」拿回一批结构化的 JSON 商户数据。
1.1 这个案例要拿到什么
- 以某个商圈为圆心、若干米为半径,按关键词(比如「火锅」)搜回的商户清单,一家一行;
- 商户名称、分类、评分、评论数、人均消费;
- 商户地址全文,并拆成「行政区 + 商圈 + 详细地址」;
- 商户经纬度(接口直接给),以及营业时间;
- 按评分分组或按人均消费分组做统计,看客单价分布。
1.2 这个案例的难点在哪
| 难点 | 具体表现 | 对策 |
|---|---|---|
| 要走开放接口 | 接口需要 key,有免费额度与调用上限 | 先在高德开放平台注册、申请 key,把「额度」写进采集计划 |
| 接口分页 | 一次只返回部分结果,需要翻页 | 按 page / offset 翻页,直到没有新结果为止 |
| 地址是一整串 | 「某市某区某某路 123 号 A 座 2 层」 | 拆成行政区、商圈、详细地址三列,剩余部分保留 |
| 名称带门店后缀 | 「某某火锅(文三路店)」 | 保留原名,另加一列「门店」便于按品牌聚合 |
| 人均消费常缺省 | 接口不一定返回人均消费 | 缺失就留空并统计缺失率,不要填 0 |
1.3 采集范围与边界
商户的名称、分类、评分、人均消费、地址,属于平台面向公众公开展示的经营信息。这一篇的路线是「接口优先」:能用官方开放平台,就不要去爬页面。要特别注意:商户经营者或店主的姓名、手机号、微信,以及用户评论里的个人信息,一律不采。
目标站点与交付产物
下表是本篇用到的真实站点。绿色是课堂可稳定复现的示范站点;橙色是延伸站点,多数有登录墙或风控,课堂上只讲结构、原理与合规边界,不教绕过。
| 项目 | 内容 |
|---|---|
| 示范站点 | 高德开放平台 · 周边搜索 API 文档 https://lbs.amap.com/api/webservice/guide/api-advanced/search 有官方接口与免费额度,返回 JSON 含名称/地址/评分/分类,是最合规的示范路线 |
| 延伸站点 |
|
| 交付产物 |
|
| 难度 | ★★☆ 中 |
| 合规提示 | 优先使用官方开放平台 API 与免费额度;不得采集商户联系人电话、不得用于电话营销。使用地图数据须遵守平台服务条款。 |
二、数据源与字段设计
目标数据源:高德地图开放平台 · 周边搜索 API,平台入口 https://lbs.amap.com/api/webservice/guide/api-advanced/search。
| 项目 | 内容 |
|---|---|
站点名称 | 高德地图开放平台(Web 服务 API · 周边搜索) |
入口网址 | https://lbs.amap.com/api/webservice/guide/api-advanced/search(注册开发者 → 创建应用 → 申请 key) |
接口与形态 | GET https://restapi.amap.com/v3/place/around,常用参数 key(你的密钥)、location(中心点经纬度)、keywords(关键词)、radius(半径)、types(分类)。返回结构化 JSON,含名称 / 地址 / 分类 / 经纬度等字段 |
实际规模 | 单次请求返回一页商户,翻页可到数百条;受免费额度与 QPS 限制 |
延伸站点 | 大众点评 https://www.dianping.com/guangzhou、高德地图网页版 https://www.amap.com/——强反爬、有条款,课堂上只讲原理与合规边界,不教绕过;美团等移动端平台没有面向公众的网页频道,此处只作说明 |
2.1 完整字段表(12 个字段)
下表就是本案例的验收标准。接口原生返回「名称 / 分类 / 地址 / 经纬度」等字段;评分、人均消费、评论数、营业时间部分来自接口的其他字段或详情补充,缺失时按口径留空。
| 字段名 | 字段含义 | 示例值 | 口径与备注 |
|---|---|---|---|
商户名称 | 店铺全名 | 某某老灶火锅(珠江新城店) | 接口 name 字段,保留原文含门店后缀 |
分类 | 多级行业分类 | 餐饮服务;中餐厅;火锅店 | 接口 type 字段,分号分隔;另拆出一级分类 |
评分 | 平台评分(5 分制) | 4.6 | 接口 biz_ext.rating,数字保留两位小数 |
人均消费 | 人均消费金额(元) | 85 | 接口 biz_ext.cost,常缺省;缺失留空不填 0 |
评论数 | 累计评价条数 | 3261 | 热度指标;接口不返回时留空并备注 |
行政区 | 所在行政区 | 天河区 | 由 adname 得到,或从地址拆出 |
商圈 | 所在商圈 | 珠江新城 | 由 business_area 得到,优先用接口值 |
详细地址 | 去掉行政区商圈后的地址 | 某某路 123 号 A 座 2 层 | 由 address 去除行政区商圈后得到 |
经度 | 地理经度 | 113.324520 | 接口 location 的经度部分,直接可用 |
纬度 | 地理纬度 | 23.106610 | 接口 location 的纬度部分,直接可用 |
营业时间 | 营业时段 | 10:00-22:00 | 接口 biz_ext.opentime_today(今日)或 biz_ext.opentime_week(一周表述),格式不一时照录 |
POI 编号 | 平台唯一标识 | B00140NF2G | 接口 id 字段,作用户去重与追溯的主键 |
2.2 地址文本的结构化(本案例的关键动作)
接口给的地址几乎总是一整串文字,直接入库没法按区域统计,必须拆开。拆法有固定套路:先识别行政区,再识别商圈,剩下的就是详细地址。
原始地址:广东省广州市天河区珠江新城某某路 123 号 A 座 2 层
拆解:
行政区 = 天河区 (接口 adname 字段直接给)
商圈 = 珠江新城 (接口 business_area 字段直接给,优先用它)
详细地址 = 某某路 123 号 A 座 2 层 (剩余部分)
注意:接口没给商圈的,留空并备注,不要硬套一个。
business_area 比从地址里猜要准得多;实在没有,再从地址里提取。课程思政|诚信与职业操守 · 能走正门,就不要翻墙
商户的评分、人均消费是面向所有消费者公开的经营信息,但点评类平台往往在条款里明确禁止抓取。这一篇改走官方开放接口,就是为了示范一件事:拿到数据的方式,和数据的价值一样重要。有正门可走时,翻墙不是本事。
AI 助手小贴士|地址与分类拆分最容易出错。先让 AI 用 5 条接口返回的样本试拆,你看一眼拆得对不对,再放开到全部。
打开 WorkBuddy 或任意 AI 对话工具,试试这样问:请先只处理这 5 条高德接口返回的样本,把「一级分类、行政区、商圈、详细地址、经度、纬度」分别列出来,先不要处理全部数据。
三、零代码操作步骤
工具与技能|先看清三个角色,再动手
本篇全程零代码:你把要求说清楚,AI 去执行,你负责验收。三个角色分工如下——浏览器技能指的是腾讯开源的 BrowserSkill,它能让 AI 直接操作你电脑上真实的浏览器(可复用已经登录的状态),自己开一个独立窗口干活,不打扰你正在看的网页;遇到验证码、登录或确认弹窗,它会停下来交给你本人处理。
| 角色 | 负责什么 | 在本案例里具体做什么 |
|---|---|---|
| 你 | 确认字段清单、验收结果、清洗与合规把关 | 盯字段清单、核对结果、处理异常(如验证码) |
| WorkBuddy | 接中文指令:探字段 → 批量采 → 清洗 → 导出交付物 | 拆解本篇的采集任务并跑完全量、产出交付物 |
| 浏览器技能 BrowserSkill | 以真实浏览器打开页面:跑脚本渲染、滚动 / 翻页 / 点开详情、截图留证;可复用本机浏览器已登录状态,遇到验证码或登录弹窗会停下来交给你处理 | 先用 key 请求周边搜索接口拿到 JSON,再核对地址怎么拆 |
五步操作主线(全课程统一,每一篇都按这个顺序推进):
- 定目标与字段:先看本篇第二节的字段表,把「要哪几列、每列什么口径、要多少条」说清楚——字段清单就是验收标准,说不清就会拿回一张字段乱七八糟的表。
- 现场踩点(浏览器技能 BrowserSkill):打开
https://lbs.amap.com/api/webservice/guide/api-advanced/search申请一个「Web 服务」类型的 key,看清请求参数与返回字段。 - 小样试采(WorkBuddy):先用这个 key 请求一次周边搜索,把返回的 JSON 字段结构列出来。
- 核对与清洗:① 名称、分类、地址、经纬度、评分、人均消费是不是都取到了;② 「行政区 + 商圈」拆得准不准;③ 翻页到没有新商户为止,停了没有。
- 导出与归档:导出交付物(数据明细表 / 可筛选明细页 / 数据看板 / 可复用的技能包),文件名带上采集日期,并写清数据来源、采集时间与已知局限。
用浏览器技能 BrowserSkill 打开 https://lbs.amap.com/api/webservice/guide/api-advanced/search(高德开放平台 · 周边搜索 API 文档),把这一页每条记录能采到的字段名和示例值列出来,先不要采集。下面是在 WorkBuddy 里完成本案例的完整流程。第一步不是采集,而是先去申请 key。
- 申请 key。打开
https://lbs.amap.com/api/webservice/guide/api-advanced/search,注册开发者账号、创建应用,申请一个「Web 服务」类型的 key。 - 把需求讲清楚。新建对话,粘贴提示词,把中心点商圈、关键词、半径和你的 key 说明清楚。
- 先试一次请求。说「先用这个 key 请求一次周边搜索,把返回的 JSON 字段结构列给我看」。
- 核对字段。看名称、分类、地址、经纬度、评分、人均消费是不是都取到了;缺失的字段有哪些。
- 试拆地址。让它先拆 5 条,你核对「行政区 + 商圈」拆得准不准。
- 翻页采全。说「继续翻页,直到没有新商户为止,并按 POI 编号去重」。
- 分组统计。说「按行政区统计商户数量;按评分区间、人均消费区间各做一份分布统计」。
- 导出并归档。说「导出为 Excel,文件名
shops_20261008.xlsx」。
四、提示词模板与追问技巧
下面这段可以直接复制。注意:网址与接口路径写全、字段按编号列清、把「用开放接口」和额度控制交代死。
请帮我调用高德地图开放平台的「周边搜索」接口,采集一批商户信息,做一张门店清单表。
【平台与接口】
平台入口:https://lbs.amap.com/api/webservice/guide/api-advanced/search
接口路径:GET https://restapi.amap.com/v3/place/around
我已在平台申请了 Web 服务类型的 key,请求参数包括:
key(我的密钥)、location(中心点经纬度)、keywords(关键词)、radius(半径)、types(分类)、page(页码)
【采集范围】中心点取「珠江新城」,半径 2000 米,关键词「火锅」,翻页采全部结果。
【需要字段】按这个顺序:
1. 商户名称(接口 name,保留原文含门店后缀)
2. 分类(接口 type,分号分隔;另拆出一级分类)
3. 评分(接口 biz_ext.rating,5 分制,两位小数)
4. 人均消费(接口 biz_ext.cost,单位元;缺失留空,不要填 0)
5. 评论数(接口不返回则留空并备注)
6. 行政区(接口 adname)
7. 商圈(接口 business_area,优先用它)
8. 详细地址(address 去掉行政区商圈后的部分)
9. 经度(location 的经度部分)
10. 纬度(location 的纬度部分)
11. 营业时间(接口 biz_ext.opentime_today / biz_ext.opentime_week,格式不一时照录)
12. POI 编号(接口 id,作为去重与追溯的主键)
【处理口径】
- 地址请拆成「行政区 + 商圈 + 详细地址」三列,商圈优先取接口 business_area
- 拆不出来或接口没给的,留空并备注,不要硬套
- 经纬度直接取接口值,不要自己换算
【合规要求】
- 这是我的账号申请的 key,只用于本课程任务;请遵守平台的调用额度与频率限制
- 只采接口返回的经营信息;店主姓名、手机号、微信一律不要采集
- 结果导出为 shops_20261008.xlsx
4.1 三条常用追问指令
追问一(额度与频率):
请把请求节奏放慢,遵守免费额度的限制,
并告诉我这一次一共调用了多少次接口。
追问二(地址与分类拆分):
请把地址拆成「行政区 + 商圈 + 详细地址」三列,
分类拆出「一级分类」列;拆不出来的留空并备注「未标注」。
追问三(分组统计):
请按行政区统计商户数量并降序;
再按评分区间 4.5 以上 / 4.0-4.5 / 4.0 以下统计分布;
再按人均消费 0-50、50-100、100-200、200 元以上统计分布。
AI 助手小贴士|多城区采集时,先让 AI 说明它识别行政区用的是什么规则(接口字段还是地址匹配),能帮你判断拆分是否可靠。
打开 WorkBuddy 或任意 AI 对话工具,试试这样问:请说明你拆分行政区时依据的是什么(接口 adname 还是从地址匹配),并举三条例外情况(拆不出来的)给我看。
五、结果核对、清洗与保存
接口返回并整理后的结果样例(节选,示例数据,均为真实字段形态):
| 商户名称 | 分类 | 评分 | 评论数 | 人均消费 | 行政区 | 商圈 | 详细地址 | 经度 | 纬度 | 营业时间 |
|---|---|---|---|---|---|---|---|---|---|---|
| 某某老灶火锅(珠江新城店) | 餐饮服务;中餐厅;火锅店 | 4.6 | 3261 | 85 | 天河区 | 珠江新城 | 某某路 123 号 A 座 1 层 | 113.324520 | 23.106610 | 10:00-22:00 |
| 街角咖啡(珠江新城店) | 餐饮服务;咖啡厅 | 4.8 | 1874 | 42 | 天河区 | 珠江新城 | 某某路 88 号 | 113.320115 | 23.118230 | 08:30-21:00 |
| 老字号面馆(体育西店) | 餐饮服务;中餐厅;面馆 | 4.3 | 940 | 26 | 天河区 | 体育西路 | 某某街 5 号 101 | 113.319870 | 23.132450 | 07:00-20:30 |
| 欢聚烤肉(天河北店) | 餐饮服务;中餐厅;烧烤 | 4.5 | 2130 | 156 | 天河区 | 天河北 | 某某中心 3 层 | 113.331020 | 23.145880 | 11:00-23:00 |
5.1 四步清洗,一句话一条
① 数值化:
把评分、评论数、人均消费三列从文本转成数值型;
单位统一为「分」「条」「元」,另设说明。
② 地址与分类归一:
行政区由接口 adname 直接取;商圈优先取 business_area;
分类拆出「一级分类」列;拆不出来的在备注列写「未标注」。
③ 门店拆分:
把商户名称里括号内的部分单独存到「门店」列,
商户名称去掉括号内容后存为「品牌名」。
④ 分组统计:
按行政区统计商户数量;
按评分区间与人均消费区间输出分布表。
5.2 保存与归档
shops_20261008.xlsx 原始明细表
shops_20261008_clean.xlsx 清洗版(数值化 + 地址归一 + 门店拆分)
shops_stats_20261008.xlsx 统计附录:行政区分布、评分分布、人均消费分布
shops_20261008_log.txt 日志:中心点、关键词、半径、接口调用次数、条数
AI 助手小贴士|核对条数时,除了看总数,还要按行政区分别数一遍,否则某个区域漏采或漏翻页很难发现。
打开 WorkBuddy 或任意 AI 对话工具,试试这样问:请按行政区分别统计商户数量,并与我预期的数量对比,指出哪个区域可能漏采或漏翻页了。
课程思政|数据安全与法治素养 · 接口有额度,数据有条款
开放平台的 key 是绑定在你个人账号上的,额度、频率、用途都有条款约束。把 key 分享给同学、拿采集结果去做二次售卖,都可能违反服务协议。合规不只是「不违法」,还包括「守约定」——按额度用、按范围采,才是一个开发者该有的样子。
六、常见问题与合规红线
6.1 这个数据源上最容易踩的五个坑
| 现象 | 原因 | 怎么处理 |
|---|---|---|
| 请求返回错误码、提示 key 无效 | key 类型不对(用了 JS 类型去调 Web 服务)或额度用尽 | 改用「Web 服务」类型的 key,并检查当日额度 |
| 只拿到十几家就没了 | 接口分页,没继续翻页 | 明确要求「继续翻页直到没有新结果」 |
| 商圈列大量为空 | 接口没返回 business_area,或没设置商圈参数 | 留空并备注「未标注」,不要硬套 |
| 人均消费整列是空的 | 接口对该类目不返回 cost | 统计缺失率并如实说明,不要填 0 参与平均 |
| 同一家店出现两次 | 不同关键词或不同中心点重复命中 | 按 POI 编号去重 |
6.2 三条合规红线(每个案例都要过一遍)
- 只采公开经营信息。店主姓名、电话、微信,以及评论中的个人信息,一律不采、不存、不导出。
- 用接口守额度。使用自己申请的 key,遵守平台的调用额度、频率与用途条款;不借 key、不转卖数据。
- 不用于商业用途。结果仅用于课程分析,不转售、不对外发布原始数据。
课程思政|工匠精神与严谨求实 · 从一整串文字里,抠出能被统计的字段
「广东省广州市天河区珠江新城某某路 123 号 A 座 2 层」——对普通人来说这就是一个地址,对数据工作者来说,它是行政区、商圈、详细地址三个待拆的字段。肯不肯把这串文字拆干净,直接决定了后面能不能按区域做统计。严谨,就是把别人眼中的一句话,变成能被计算的几列。
七、随堂自测(10 题)
点击选项即可判分,答错的题会立刻显示解析。
1采集本地生活商户信息,本案例推荐的、最合规的路线是?
- A. 直接爬点评类页面
- B. 用官方开放平台 API:申请 key → 调接口 → 拿结构化 JSON
- C. 用手机模拟器绕过风控
- D. 找别人买一份现成数据
2采集某城区商户信息之前,最该先确认的是?
- A. 数据源是否公开或已授权,并规划好调用频率与额度
- B. 商户招牌的颜色
- C. 自己的手机型号
- D. 要不要先注册会员
3商户人均消费写成「85 元」「¥85/人」两种,第一步应该怎么处理?
- A. 原样保留,方便阅读
- B. 把「元」字删掉就好
- C. 只保留最大的那个数
- D. 统一抽取成纯数字,单位单独列一列
4地址「广东省广州市天河区珠江新城某某路 123 号」,按本案例口径应该怎么处理?
- A. 整串原样放进一列
- B. 只保留最后两个字
- C. 拆成行政区、商圈、详细地址三列
- D. 翻译成英文再保存
5商户名称是「某某老灶火锅(珠江新城店)」,合理的处理是?
- A. 直接删掉括号部分
- B. 只保留括号里的内容
- C. 当成两家不同的商户
- D. 保留原名,另加一列「门店」
6用高德周边搜索接口时,返回的经纬度字段主要有什么用?
- A. 可以直接落到地图上做散点与热力分析
- B. 没什么用,可以删掉
- C. 用来替代地址字段
- D. 只是界面好看
7要按评分做分组统计之前,最该先做的事是?
- A. 把没有评分的商户全部删掉
- B. 把所有评分乘 10
- C. 确认所有商户的评分是同一口径(如都是 5 分制)
- D. 先按评论数排序
8下面哪种做法符合本课的合规要求?
- A. 采集商户店主手机号用于课程分析
- B. 只采公开展示的经营信息、控制频率、不采个人联系方式
- C. 把采集到的商户数据卖给同行
- D. 用高频请求把整站商户一次抓完
9使用开放平台 API 时,最该注意的一条是?
- A. 遵守平台服务条款与调用额度,不要超量或转售数据
- B. key 写在代码里最方便
- C. 把 key 分享给同学一起用
- D. 无限制地反复调用
10保存本地生活数据时的好习惯是?
- A. 只保留最后一张统计图
- B. 原始表、清洗表、分组统计表分开保存,并记录采集日志
- C. 直接用清洗结果覆盖原始文件
- D. 把所有数据塞进一个单元格