7.6 KiB
Place ID 是 Google Maps/Places API 中用于唯一标识一个地点(place)的字符串,常用于构建 URL(如 https://maps.google.com/?place_id=ChIJ...)或调用 Places API(如 Place Details)。
最简单的方法:使用 Google 官方 Place ID Finder
-
打开 Google 的 Place ID Finder 工具:
-
在搜索框中输入地点名称、地址或关键词(例如“上海东方明珠”或具体地址)。
-
从下拉建议或地图上选择正确的地点。
-
工具会自动显示 Place ID(以
ChIJ开头的一长串字符),直接复制即可。
这个方法最推荐,不需要写代码。
通过 Google Maps 网页手动获取(无需 API)
- 在 Google Maps 搜索并打开你要的地点页面。
- 点击 分享 → 嵌入地图(Embed a map),或直接查看页面源代码(右键 → 查看页面源代码,搜索 “place_id” 或 “ChIJ”)。
- 有些 Chrome 扩展(如 “Place ID Finder for Google Maps”)可以点击地点后直接显示 Place ID。
通过 Places API 编程获取(推荐用于批量或自动化)
使用 Text Search(文本搜索)、Nearby Search(附近搜索)或 Find Place 等接口,响应结果中会包含 place_id。
示例(Text Search):
https://maps.googleapis.com/maps/api/place/textsearch/json?query=你的地点名称&key=YOUR_API_KEY
响应中会有 "place_id": "ChIJ..."。
然后可以用这个 Place ID 调用 Place Details 获取更多信息,或拼接到 URL 中。
构建带 Place ID 的 Google Maps URL
- 简单格式:
https://www.google.com/maps/place/?q=place_id:你的PlaceID - 或者:
https://maps.google.com/?place_id=你的PlaceID(你提到的格式) - 推荐搜索动作:
https://www.google.com/maps/search/?api=1&query_place_id=你的PlaceID
注意:
- Place ID 长期稳定,但 Google 建议如果超过 12 个月,最好刷新一次。
- 使用 Places API 需要启用对应服务并获取 API Key,会有费用(免费额度有限)。
- 对于某些服务区企业(无实体地址),可能需要额外技巧(如查看 “Write a review” 按钮的 data-pid)。
如果你有具体地点名称或地址,告诉我,我可以帮你进一步说明!
是否可以将这个程序封装成有gui的界面程序。在界面上加载一个google 地图,或者百度地图之类,通过鼠标可以选择任何一个点,获得其经纬度! 同时,界面提供一个输入框,允许用户输入查询的关键字,如 咖啡店 最终查询的效果可能跟这个命令行差不多!? npm run scrape "https://www.google.com/maps/place/The+Coffee+Shop/@40.7484,-73.9857,17z"
我的上述需求,是否可以实现?
● 完全可以实现。这个需求的核心是把现有的 CLI 流程变成一个带地图交互的 GUI。
方案分析
有几种实现路径:
方案 A:浏览器 Web 应用 + 本地服务(推荐)
在现有 Node.js 项目基础上,添加一个本地 Web 服务器和前端页面:
- 地图:使用 Leaflet + OpenStreetMap(免费、无需 API Key、全球覆盖)
- 交互:点击地图任意位置获取经纬度,搜索框输入关键词(如 "咖啡店")
- 后端:复用现有的 src/placesApi.ts、src/transformer.ts 等全部代码,通过 API 端点暴露
- 结果展示:在页面上直接渲染 JSON/Markdown 结果
优点:无需额外依赖、免费地图、完全复用现有代码、浏览器打开即用
方案 B:Electron 桌面应用
打包成独立的桌面窗口应用,内嵌地图。
优点:更像"桌面软件" 缺点:Electron 体积大(~150MB),对这个小工具来说过重
方案 C:Python GUI(Tkinter/PyQt + WebView)
优点:Python 生态丰富 缺点:需要把 TypeScript 逻辑用 Python 重写一遍,重复劳动
建议
方案 A 最合理。具体来说就是:
浏览器打开 localhost:3000 ├── 左侧/上方:Leaflet 地图(OSM 瓦片,免费) │ ├── 点击任意位置 → 获取经纬度 │ └── 搜索框输入 "咖啡店 北京" ├── 右侧/下方:结果展示 │ ├── JSON 选项卡 │ └── Markdown 选项卡 └── 后端:Express 提供 /api/search?lat=xxx&lng=xxx&keyword=xxx
工作流程:
- 用户在地图上点击,或在搜索框输入关键词
- 前端发送经纬度 + 关键词到后端
- 后端调用 Google Places API(Nearby Search 或 Text Search)
- 返回结果在前端渲染展示
更好的做法是直接用 Places API 的 nearby search(基于坐标搜索周边),而不是原来的 URL 解析方式,这样更自然匹配地图点击的交互。
要我按方案 A开始实现吗?大概需要新增 2-3 个文件(Express 服务端 + HTML 前端页面),不改动现有的 src/ 代码。
首先需要确认你的代理是否配置好了。
步骤:
- 在 .env 中配置代理
HTTPS_PROXY=http://127.0.0.1:你的代理端口
你的代理地址是什么?比如 Clash 一般默认 http://127.0.0.1:7890,V2Ray 一般是 http://127.0.0.1:10809。
- 启动
npm run gui
看到终端输出 Using proxy: http://... 就说明代理生效了。
- 使用方式
代理已经正常工作了! 但 Google 返回了 403 错误,原因是你 API Key 的限制。
问题
Google API returned:The provided API key has an IP address restriction. The originating IP address of the call (62.72.181.132) violates this restriction.
你的 API Key 在 Google Cloud Console 里设置了 IP 地址白名单,而你的代理出站 IP(62.72.181.132)不在白名单里。
解决方法
去 Google Cloud Console 修改 API Key 的限制:
- 打开 https://console.cloud.google.com/apis/credentials
- 找到你的 API Key:AIzaSyBShHAVWz4caxrAy6X1Abxw4iTXjnSUv3U
- 在 应用限制(Application restrictions) 中: - 把 62.72.181.132 加入白名单地址 - 或者直接设为 "无限制"(None)(最简单)
改完后重新 npm run gui 即可。
代码本身的修复总结:
- 用 undici 的 setGlobalDispatcher() 来设置代理(而非每个请求手动传 dispatcher),解决了 Node.js 内置 fetch 和 npm undici 版本不兼容的问题
- 修复了 .env 值的前导空格 bug
- 启动时添加了连通性检测,直接可以判断代理和 API Key 是否正常
总结一下排查结果:
发现的问题
- Bug 修复: places:searchNearby 不支持 textQuery 参数
Google Places API 的 Nearby Search 端点不支持关键词搜索 — 它只接受 includedTypes(预定义的场所类型)。"coffee shop" 这种自由文本只能用 Text Search。
修复: 当有关键词时,自动路由到 places:searchText(Text Search),只在纯坐标搜索时用 places:searchNearby。
- 网络问题: Google API 在国内被墙
你的服务器日志显示的:
[ERROR] Network error during search: TypeError: fetch failed
我用 curl 直接测试确认:
- Connection timed out after 10015 milliseconds
places.googleapis.com 无法从你的网络直接访问
修复: 添加了代理支持。在你的 .env 中加上:
HTTPS_PROXY=http://127.0.0.1:7890 # 换成你的代理地址
然后重新 npm run gui 即可。服务器启动时会显示 Using proxy: http://...。