地图搜索接口给你一屏商家列表:名字、评分、地址、电话。但做竞对调研或选址分析时,经常还要更细的东西——营业时间、photos、官网、精确坐标。这些在列表条目里是缩略的,得再查一次详情接口。这篇把"搜索 → 挑出目标 → 拉详情"这条两步流水线走通。
先搞清两步各干什么
- /google/maps/search:给关键词(可选配 lat/lng + zoom),返回 places 数组,每个元素是一个商家条目,其中带着 feature_id。
- /google/maps/detail:给 feature_id,返回单个 place 对象,字段比列表全:营业时间 hours、open_status、photos、website、google_maps_url 等。
关键是那个 feature_id:格式形如 0x…:0x…,必须用地图搜索返回里的值,不能自己编,也不能拿响应里的 place_id 顶上(详情接口只认 feature_id)。编一个格式正确但不存在的 id,会得到 1004 NOT_FOUND。
计费上两个接口都是 2 credits 一次,所以"搜索 1 次 + 详情 N 次"的成本 = 2 + 2N——别无脑把列表里每一家都拉一遍详情,先按条件筛。
参数与字段定义以 SerpBase 官方文档 为准。
两步流水线脚本
import requests
API = "https://api.serpbase.dev"
KEY = "你的 API Key"
HEADERS = {"X-API-Key": KEY, "Content-Type": "application/json"}
def maps_search(q: str, lat=None, lng=None, zoom=14) –> list:
body = {"q": q}
if lat is not None and lng is not None: # 坐标必须成对出现
body.update({"lat": lat, "lng": lng, "zoom": zoom})
resp = requests.post(f"{API}/google/maps/search",
headers=HEADERS, json=body, timeout=30)
data = resp.json()
if data.get("status") != 0:
raise RuntimeError(f"search: {data.get('error')}")
return data.get("places", [])
def maps_detail(feature_id: str) –> dict:
resp = requests.post(f"{API}/google/maps/detail",
headers=HEADERS,
json={"feature_id": feature_id}, timeout=30)
data = resp.json()
if data.get("status") != 0:
raise RuntimeError(f"detail: {data.get('error')}")
return data.get("place", {})
places = maps_search("咖啡店", lat=31.2304, lng=121.4737, zoom=14)
# 只给"有电话但没有官网"的商家补详情——省 credits 的筛法
targets = [p for p in places if p.get("phone") and not p.get("website")]
for p in targets[:5]: # 前 5 家,10 credits
d = maps_detail(p["feature_id"])
print(d.get("name"), "|", d.get("website"), "|",
d.get("hours"), "|", d.get("open_status"))
城市级查询时把 lat/lng 设成市中心坐标、zoom 取 13~15,能压住结果范围;坐标不配对传,接口会直接拒。
详情里最值钱的几个字段
| hours / open_status | 竞对营业时段分析、实时"现在开没开" |
| photos | 盯竞对门店焕新:photo 数量/更新是装修信号 |
| website | 判断哪些商家还没有独立站(获客线索) |
| rating + 列表评分 | 单店详情页评分更细,可复核列表数据 |
| google_maps_url | 存档用,方便人工复核与截图 |
筛选条件配不同行业换一下:找"评分高但没官网"的本地服务商,找"hours 缺失"的疑似歇业门店,都是同一套两步流程换个 WHERE。
成本与节奏
单店详情 2 credits。按上面的筛法,一轮"搜索 1 次 + 详情 5 次"是 12 credits;100 次免费试用够完整跑三四轮,足够确认字段质量和筛法是否合理再放量。跑批量时给详情请求加 1~2 秒间隔,限流了(1029)就退避。
FAQ
feature_id 和 place_id 有什么区别? 都在返回里,但详情接口的入参只收 feature_id(data_id 是它的别名);place_id 是 Google 体系里的另一种标识,这里当入参用会被拒。
搜索结果里已经有 rating 了,为什么还要详情? 列表是快照,详情是全集。做历史对比(比如盯评分变化、photo 增量)时,必须以详情接口的稳定口径为准。
详情请求失败会扣 credits 吗? 失败响应 credits_charged 为 0,不扣;所以放心按 feature_id 重试,别怕成本。
把脚本里的筛选条件换成你行业的判断标准,先跑 5 家看详情字段质量,再决定要不要铺全城。



