如何通过Google Places API获取英国全部汽车维修店数据?
解决Google Places API大半径搜索结果受限的问题
问题分析
你遇到的60条结果限制是Google Places API Nearby Search的固有机制:当搜索范围过大时,API仅会返回最相关的前60条结果(分3页,每页20条),不会返回全部数据,这和地图低缩放级别下不显示全部POI的逻辑一致。
可行解决方案
1. 区域网格划分+小半径遍历
这是最可靠的方案,核心是把英国划分为多个无重叠(或最小重叠)的网格区域,每个区域用小半径(推荐5-10公里)发起搜索,确保覆盖所有区域的POI:
- 先确定英国的经纬度范围:大致纬度50°N-59°N,经度-8°W-2°E
- 按固定步长生成网格中心:比如每0.09°(约10公里)生成一个坐标点,覆盖整个英国
- 对每个网格中心发起Nearby Search,收集结果后用
place_id去重
2. 结合Text Search API补充
对于偏远区域,Nearby Search可能覆盖不足,可使用Text Search API针对细分区域(比如"car repair in Cornwall")发起搜索,补充结果。
3. 优化请求效率
- 用异步请求(如
aiohttp)替代同步请求,提升数据采集速度 - 根据API配额调整请求间隔,避免触发限流
- 本地缓存已获取的
place_id,避免重复请求Place Details API
修改后的代码示例
import requests import time import json from math import ceil # 英国大致经纬度范围 MIN_LAT = 50.0 MAX_LAT = 59.0 MIN_LNG = -8.0 MAX_LNG = 2.0 # 网格步长(约10公里,0.09°对应约10公里) STEP = 0.09 # 搜索半径(10公里) RADIUS = 10000 TYPE = "car_repair" API_KEY = "YOUR_API_KEY" def generate_grid_centers(): """生成覆盖英国的网格中心坐标""" centers = [] lat_steps = ceil((MAX_LAT - MIN_LAT) / STEP) lng_steps = ceil((MAX_LNG - MIN_LNG) / STEP) for i in range(lat_steps): lat = MIN_LAT + i * STEP for j in range(lng_steps): lng = MIN_LNG + j * STEP centers.append(f"{lat},{lng}") return centers def get_nearby_places(location, radius): """获取单个位置附近的所有place_id""" place_ids = [] pagetoken = "" while True: time.sleep(2) url = f"https://maps.googleapis.com/maps/api/place/nearbysearch/json?location={location}&radius={radius}&type={TYPE}&key={API_KEY}&pagetoken={pagetoken}" response = requests.get(url) res_json = response.json() if "results" not in res_json: break place_ids.extend([item["place_id"] for item in res_json["results"]]) if "next_page_token" in res_json: pagetoken = res_json["next_page_token"] else: break return place_ids def get_place_details(place_id): """获取单个place_id的详细信息""" time.sleep(2) url = f"https://maps.googleapis.com/maps/api/place/details/json?place_id={place_id}&fields=name,formatted_address,formatted_phone_number,rating,review,opening_hours&key={API_KEY}" response = requests.get(url) res_json = response.json() return res_json.get("result", {}) if __name__ == "__main__": all_place_ids = set() # 用集合自动去重 grid_centers = generate_grid_centers() print(f"共生成{len(grid_centers)}个网格中心") # 遍历所有网格获取place_id for idx, center in enumerate(grid_centers): print(f"处理第{idx+1}/{len(grid_centers)}个网格") ids = get_nearby_places(center, RADIUS) all_place_ids.update(ids) print(f"去重后共获取{len(all_place_ids)}个place_id") # 获取详细信息 all_data = [] for idx, place_id in enumerate(all_place_ids): print(f"获取第{idx+1}/{len(all_place_ids)}个店铺信息") details = get_place_details(place_id) if details: all_data.append(details) # 保存数据 with open("uk_car_repairs.json", "w", encoding="utf-8") as f: json.dump(all_data, f, ensure_ascii=False, indent=2) print("数据保存完成")
注意事项
- 确保API有足够配额:每个Nearby Search请求算1个配额,每个Place Details请求算1个配额,大区域采集会消耗大量配额
- 可根据实际情况调整网格步长和搜索半径,平衡覆盖范围与请求数量
- 若遇限流,延长请求间隔或申请提高API配额
内容的提问来源于stack exchange,提问作者Ameen Izhac
相关产品推荐
相关产品推荐

