如何使用AI代理和Scrapeless MCP服务器大规模抓取谷歌地图(Google Maps)
关键要点:
- 适用于任何支持MCP的客户端。 Scrapeless MCP Server将云浏览器作为一组模型上下文协议工具暴露——Claude Desktop、Claude Code、Cursor、OpenAI Codex CLI、Gemini CLI、VS Code + GitHub Copilot Chat,或根据MCP TypeScript SDK构建的自定义客户端都以相同的方式调用它们。协议是承重的,而不是客户端。没有SDK胶水,也没有CLI子进程管理。
- 浏览器原语组合成谷歌地图爬虫。 服务器提供通用的浏览器工具——
browser_create、browser_goto、browser_wait_for、browser_get_html、browser_get_text、browser_click、browser_type、browser_press_key、browser_scroll、browser_scroll_to、browser_screenshot、browser_snapshot、browser_close—— 代理将它们组合成谷歌地图所需的搜索→滚动→提取流程。 - 两种传输模式。 Stdio模式通过
npx scrapeless-mcp-server在本地运行服务器,是工作站上的桌面MCP客户端的正确默认设置。HTTP可流模式将客户端指向https://api.scrapeless.com/mcp,是云托管代理的正确默认设置。 - 云渲染加上住宅代理。 谷歌地图是一个JavaScript密集型的单页应用,结果以饲料的形式懒加载。Scrapeless Scraping Browser处理每个会话的JS渲染、住宅代理出口和反检测指纹识别——代理只需驱动页面。会话通过Scrapeless账户配置的代理区域进行分配;今天MCP工具界面没有暴露每次调用区域的覆盖。
- 每个查询结果列表限制。 谷歌地图在侧边饲料中每个查询最多显示120个结果。超过这一点,策略是地理网格:将搜索区域划分为更小的边界框,每个边界框运行一个查询,并按地点ID去重。
- 免费开始。 新的Scrapeless账户包括免费的Scraping Browser运行时——在Scrapeless注册。
介绍:一种MCP原生路径获取谷歌地图数据
谷歌地图是开放网络上最丰富的公共商业数据集之一——每个条目的名称、地址、评级、评论数、营业时间、照片链接、类别标签、联系信息以及稳定的地点ID。对于地方SEO团队、潜在客户生成管道、房地产分析和竞争对手位置映射,这些数据集是工作流的基础。
如果没有真实的浏览器,操作页面本身是很困难的。地图视图加载其自己的SDK,侧面面板在滚动饲料时通过懒加载进行分页,单个地点详细面板通过用户点击打开,结果数在每次查询中上限约为120。纯HTTP爬虫返回的是JS外壳;数据位于呈现的DOM之后。
本帖介绍如何使用Scrapeless MCP Server与任何支持MCP的客户端——Claude Desktop、Claude Code、Cursor、OpenAI Codex CLI、Gemini CLI或根据MCP TypeScript SDK构建的自定义客户端——端到端地爬取谷歌地图。服务器将Scrapeless Scraping Browser——一个准备好的云浏览器——包装成一组MCP工具,因此代理通过协议直接调用browser_create/browser_goto/browser_scroll/browser_get_html,而不是shell到CLI或连接SDK。云浏览器处理渲染、代理和反检测层;代理处理发现→提取模式。
通过不同的集成表面获取相同目标,请参见LangChain代理帖子,或对于bash CLI版本,请参见更广泛的搜索引擎帖子。
您可以用它做什么
- 本地潜在客户生成。 拉取目标城市中每个牙医、管道工或咖啡店的名称、地址、电话、网站、营业时间、评级和评论数。
- 本地SEO竞争分析。 跟踪类别关键词查询中竞争对手位置的排名以及同一SERP上的周边列表。
- 房地产和POI数据集构建。 构建分类的兴趣点表——按菜系的餐厅、按地区的零售连锁、按邮政编码的公共服务——以滚动的频率刷新。
- 声誉跟踪。 快照每个地点的评级、评论数和评论速度,以突出异常位置。
- 市场研究。 映射目标区域内小型企业的密度和类别组合以估算市场饱和度。
- 照片和价格情报。 捕捉地点面板的屏幕截图进行可视回归,或提取每个列表的价格水平指示符(
$,$$,$$$)。
为什么选择 Scrapeless 抓取浏览器
Scrapeless 抓取浏览器是一款可定制的、反检测的云浏览器,专为网页爬虫和人工智能代理设计。特别针对 Google 地图,它提供了:
- 云端 JavaScript 渲染,使地图 SDK、侧边喂养、滚动驱动的延迟加载和地点详情面板在提取前全部填充。
- 覆盖195多个国家的住宅代理,确保地理限制查询返回本地用户会看到的列表 - 这很重要,因为 Google 地图的结果因出口区域而异。
- 每个会话的反检测指纹识别,确保页面在长滚动会话中与自然流量的渲染完全相同。
- 通过
browser_create任务 ID 实现的会话持久性;同一代理中的后续browser_*工具调用都将重用同一个云浏览器,保持 cookies、滚动位置和导航历史的一致性。 - 单一的 MCP 接口 — 代理驱动地图所需的每个操作(
browser_goto、browser_wait_for、browser_scroll、browser_click、browser_get_html、browser_get_text、browser_screenshot)都可以轻松调用。
在 Scrapeless 免费计划中获取 API 密钥。完整的 MCP 工具接口文档可以在 github.com/scrapeless-ai/scrapeless-mcp-server 找到。
先决条件
- 任何支持 MCP 的客户端。 Claude Desktop(claude.com/download)、Claude Code、Cursor、OpenAI Codex CLI、Gemini CLI、VS Code + GitHub Copilot Chat,或针对 MCP TypeScript SDK 构建的自定义客户端 — 协议是关键,而不是客户端。
- Node.js 18 或更高版本(用于标准输入输出传输模式)。
- Scrapeless 账户和 API 密钥 — 登录 Scrapeless 注册。
- 对编辑客户端 MCP 配置文件有基本的了解。
安装
Scrapeless MCP 服务器作为 scrapeless-mcp-server npm 包发布,可以从 任何支持模型上下文协议的客户端 调用。下面的四步设置显示了最常见客户端(Claude Desktop、Claude Code、Cursor、OpenAI Codex CLI、Gemini CLI)的安装路径,但 JSON 片段本身是可移植的 — 可以将其放入团队已使用的任何客户端中,调用同样的工具。
1. 获取你的 Scrapeless API 密钥
在 Scrapeless 注册,打开仪表板,然后从 设置 → API 密钥管理 创建一个密钥。复制该值 — 它将放入第 2 步的 MCP 配置中。
通过 Scrapeless 注册 获得免费计划的 API 密钥,并加入官方社区:
Scrapeless 官方 Discord 社区
Scrapeless 官方 Telegram 社区
2. 将 MCP 服务器添加到你的客户端(标准输入输出模式)
配置文件的位置取决于客户端:
Claude Desktop(来自 claude.com/download 的桌面应用):
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Claude Code(终端 CLI):
- 所有平台:
~/.claude.json - 或使用
claude mcp add子命令,而不是手动编辑文件:bashCopy
claude mcp add scrapeless --scope user --transport stdio \ --env "SCRAPELESS_KEY=YOUR_SCRAPELESS_KEY" \ -- npx -y scrapeless-mcp-server
**Cursor:**编辑 ~/.cursor/mcp.json(或使用 Cursor 的设置 → MCP 界面)。JSON 结构与下面的片段相同。
OpenAI Codex CLI: Codex 从 ~/.codex/config.toml 读取 MCP 服务器,并提供 codex mcp 辅助命令。标准输入输出安装命令是:
bashCopy
codex mcp add scrapeless \
--env "SCRAPELESS_KEY=YOUR_SCRAPELESS_KEY" \
-- npx -y scrapeless-mcp-server
等效的 TOML 是:
tomlCopy
[mcp_servers.scrapeless]
command = "npx"
args = ["-y", "scrapeless-mcp-server"]
[mcp_servers.scrapeless.env]
SCRAPELESS_KEY = "YOUR_SCRAPELESS_KEY"
编辑完文件后,重启 Codex 并使用 codex mcp list --json 确认条目。Codex 对标准输入输出的 MCP 帧有严格要求:服务器进程必须只向标准输出写入 JSON-RPC 消息。如果 Codex 报告 与 MCP 服务器握手失败、初始化响应 或 连接关闭,请检查服务器是否在 JSON-RPC 响应之前向标准输出打印了启动日志行。升级到固定的服务器版本或在服务器后面运行一个小的标准输入输出过滤器,以将非 JSON 的标准输出行重定向到标准错误。
使用标准输入模式作为默认的Codex路径。目前的Codex CLI构建提供了codex mcp add --url用于可流式传输的HTTP服务器,但助手的内置身份验证选项基于Bearer Token,而Scrapeless的托管MCP端点期望x-api-token头。仅在您的Codex版本/配置支持MCP服务器的自定义HTTP头时,才使用Codex的HTTP模式。
Gemini CLI: Gemini通过settings.json中的mcpServers支持MCP服务器,并有一个gemini mcp助手。Gemini CLI本身当前需要Node.js 20或更高版本。进行用户范围的标准输入安装,请运行:
bashCopy
gemini mcp add -s user \
-e SCRAPELESS_KEY=YOUR_SCRAPELESS_KEY \
scrapeless npx -y scrapeless-mcp-server
或直接编辑~/.gemini/settings.json:
jsonCopy
{
"mcpServers": {
"scrapeless": {
"command": "npx",
"args": ["-y", "scrapeless-mcp-server"],
"env": {
"SCRAPELESS_KEY": "YOUR_SCRAPELESS_KEY"
}
}
}
}
对于项目范围的配置,请使用.gemini/settings.json。通过gemini mcp list(或者如果您的非交互式shell未打印表格,请使用gemini --debug mcp list)确认,或启动Gemini并运行/mcp查看连接状态和发现的工具。
VS Code + GitHub Copilot Chat: 相同的mcpServers代码片段放入工作区或用户级别的MCP设置中;有关活动路径,请查阅GitHub Copilot Chat MCP文档。
在mcpServers下添加Scrapeless服务器条目:
jsonCopy
{
"mcpServers": {
"scrapeless": {
"type": "stdio",
"command": "npx",
"args": ["-y", "scrapeless-mcp-server"],
"env": {
"SCRAPELESS_KEY": "YOUR_SCRAPELESS_KEY"
}
}
}
}
将YOUR_SCRAPELESS_KEY替换为步骤1中的密钥。重新启动客户端以加载新服务器。在首次运行时,npx -y scrapeless-mcp-server将下载包并通过标准输入启动服务器—不需要单独的安装命令。重启后,客户端的MCP面板应该列出scrapeless以及其他任何已连接的服务器。
3. 或使用HTTP可流式传输模式(云托管代理)
对于远程运行的代理——托管的Cursor服务器、CI运行器、在容器中运行的自定义MCP客户端——请将客户端指向Scrapeless托管的MCP端点,而不是在本地运行npx:
jsonCopy
{
"mcpServers": {
"Scrapeless MCP Server": {
"type": "streamable-http",
"url": "https://api.scrapeless.com/mcp",
"headers": {
"x-api-token": "YOUR_SCRAPELESS_KEY"
},
"disabled": false,
"alwaysAllow": []
}
}
}
相同的YOUR_SCRAPELESS_KEY在两种模式下都有效。当标准输入二进制文件无法与代理一起运行时(CI沙箱、托管代理运行器),HTTP传输是正确的默认选择。
对于Gemini CLI,HTTP助手和JSON形状是:
bashCopy
gemini mcp add -s user -t http \
-H "x-api-token: YOUR_SCRAPELESS_KEY" \
scrapeless https://api.scrapeless.com/mcp
jsonCopy
{
"mcpServers": {
"scrapeless": {
"httpUrl": "https://api.scrapeless.com/mcp",
"headers": {
"x-api-token": "YOUR_SCRAPELESS_KEY"
}
}
}
}
4. 验证MCP服务器已连接
在第一次真正的地图抓取之前,使用一个提示对安装进行烟雾测试:
“使用Scrapeless MCP服务器打开https://example.com,并告诉我页面标题。”
代理应该调用browser_create来创建会话,然后调用browser_goto进行导航,再调用browser_get_text(或browser_get_html)并回复**“示例域”**。如果返回这个,则MCP服务器已加载,API密钥已设置,云浏览器可访问。
如果失败:
| 症状 | 可能原因 | 修复 |
|---|---|---|
| “我看不到Scrapeless工具” | 客户端未加载MCP服务器 | 重新检查配置文件路径,重启客户端,查看客户端的MCP指示器中的服务器 |
Authentication failed / 401 |
API密钥未设置或已过期 | 从仪表板重新复制密钥,粘贴到配置中,重启客户端 |
npx在第一次运行时挂起 |
网络缓慢或注册表超时 | 在终端中运行npx -y scrapeless-mcp-server一次以预先缓存包,然后重启客户端 |
Codex在MCP启动期间显示initialize response或connection closed |
标准输入服务器在MCP JSON-RPC握手前向stdout写入了非JSON文本 | 升级服务器或将其包装,以便只有JSON-RPC行到达stdout,日志进入stderr |
工具调用返回Access Denied HTML |
在新分配上代理池或反机器人挑战 | 让代理重试—browser_close然后browser_create创建一个新会话 |
你实际使用这个的方法:提示你的代理
安装后,您可以通过与您的代理交谈来抓取Google地图——而不是手动编码工具调用。MCP服务器将云浏览器公开为可发现的工具列表;代理读取工具描述,并根据提示将其组合成正确的顺序。
你可以粘贴的提示
| 你对代理说 | 你得到的回复 |
|---|---|
| "获取西雅图派克街的前30家咖啡店信息,返回JSON格式,包括名称、评分、评论数量和地址。" | 每个地点一个JSON记录,包含请求的字段 |
| "列出90015邮政编码下的每位牙医,包括电话、网站和营业时间。" | 每个地点的JSON记录,包括联系方式和营业时间 |
| "在谷歌地图上搜索'布鲁克林大桥附近的寿司餐厅',滚动到底部,返回所有信息。" | 约120个地点,按名称和地址去重 |
| "对于每个结果,还需点击详细面板并获取网站URL和完整地址。" | 每个地点的JSON记录,增加详细面板字段 |
| "滚动后对搜索结果页进行屏幕截图。" | 屏幕截图 + 提取的JSON |
| "在'旧金山'寻找意大利餐馆,筛选评分≥4.5且评论数≥200的餐馆。" | 过滤后的地点列表 |
| "从马德里IP运行相同查询——返回西班牙用户看到的地图结果。" | 本地化结果(通过西班牙的住宅代理路由) |
| "对于名为'派克街故事咖啡'的地点,打开地点面板并提取最新的10条评论。" | 详细面板评论数据 |
browser_create工具分配一个新的云浏览器并返回一个会话ID,代理随后在整个流程中使用。会话是状态的单位——cookies、滚动位置和导航历史都在其中。 |
工具调用(代理通过MCP发送的内容):
jsonCopy
{
"name": "browser_create",
"arguments": {}
}
该工具返回一个有效负载,如新浏览器会话已创建,ID为:vybp-a64d-2dqf-9vsq86。同一代理中的后续browser_*调用会自动重用该活动会话;将返回的ID作为sessionId传回是支持的,但不是必需的。
代理区域由Scrapeless账户配置设置——MCP的browser_create工具不公开每次调用的proxyCountry参数。对于需要每个查询区域控制的工作流(美国地图结果与西班牙或日本),请直接使用scrapeless-scraping-browser CLI并使用--proxy-country,或运行为不同地区配置的多个Scrapeless API密钥。
如果调用返回临时连接错误,请让代理重试一次。代理池在分配时偶尔不会返回可用的住宅IP;下次尝试时,新的browser_create将成功。
步骤2 — 导航到地图搜索URL(browser_goto)
Google地图为搜索提供了深层链接URL模式:https://www.google.com/maps/search/<query>。对查询进行URL编码,页面将加载并填充该搜索的侧边资料。
jsonCopy
{
"name": "browser_goto",
"arguments": {
"url": "https://www.google.com/maps/search/coffee+shops+in+Pike+Place+Seattle"
}
}
URL形式直接将代理带到一个填充好的SERP,而无需操作搜索框,这样可以缩短流程,减少代理可能点击错误控件的概率。
同意墙处理。 当云浏览器通过欧洲住宅代理路由时,Google会在显示地图之前,通过consent.google.com插入一个同意屏幕。代理应在browser_goto后调用browser_get_text,检查响应是否包含“同意”或“接受所有”/本地化等价词(Accetta tutto,Akzeptieren,Accepter)。如果是的话,驱动browser_click点击接受按钮——可访问的标签在不同地区有效:
jsonCopy
{
"name": "browser_click",
"arguments": {
"selector": "button[aria-label*='Accept' i], form[action*='consent'] button:last-of-type"
}
}
点击后,重复browser_goto以进入地图页面。通过美国代理区域运行的工作流通常不会遇到这个障碍。
步骤3 — 等待页面渲染(browser_wait_for)
地图SPA分批绘制:首先是地图画布,然后是侧边资料外壳,最后是地点卡。等到某个地方卡标志出现后再提取,否则结果区域将是空的。
jsonCopy
{
"name": "browser_wait_for",
"arguments": {
"selector": "a.hfpxzc"
}
}
a.hfpxzc是规范的地点链接锚——每个有机卡片在侧边资料中都有一个,地点名称在aria-label中,规范的/maps/place/<slug>/data=!1s<placeId> URL在href中。这是一个可靠的信号,表明卡片已经渲染,因为文章标志有时会在水合过程中滞后于链接锚。
如果等待超时,页面可能出现了插页(很少见)或查询的结果确实为空。请让代理调用browser_get_text以转储可见页面文本,以确认是哪个情况。
步骤4 — 滚动侧边资料以延迟加载更多结果(browser_scroll,browser_press_key)
侧边资料最初呈现约10-20个卡片。随后的批次会在滚动侧边资料时延迟加载,直到每个查询约120个地点的上限。
MCP服务器公开了两个滚动原语:
browser_scroll— 滚动页面,无需参数(它作用于活动文档)。browser_scroll_to— 滚动到绝对像素坐标。所需参数:{x, y}数字。
jsonCopy
{
"name": "browser_scroll",
"arguments": {}
}
对于Google地图,侧边资料是其自身可滚动的容器而不是页面本身,因此普通的browser_scroll可能无法推进延迟加载。可靠的模式是先通过browser_click对任何已呈现的卡片进行聚焦,然后使用browser_press_key驱动键盘滚动:
jsonCopy
{
"name": "browser_click",
"arguments": { "selector": "a.hfpxzc:first-of-type" }
}
jsonCopy
{
"name": "browser_press_key",
"arguments": { "key": "End" }
}
典型的流程是:点击第一个卡片,然后用browser_press_key点击"End"或"PageDown"三到五次,在每次按键之间等待1500毫秒,以便延迟加载在下一个按键触发之前完成。
对于深度抓取,代理应该在每次滚动后监控卡片数量:当两个连续的 browser_get_html 调用返回相同的数量时,数据源已经达到每次查询的限制,进一步滚动将不再添加结果。
第 5 步 — 提取地点卡片(browser_get_html)
一旦数据源渲染出所需数量的卡片,提取完整的 HTML 并让代理解析它。
jsonCopy
{
"name": "browser_get_html",
"arguments": {}
}
browser_get_html 返回整个渲染的 DOM 作为单个文本载荷——没有每个区域的选择器参数;代理在响应到达后在内存中切割 HTML。每一个自然卡片都呈现为一个 <a class="hfpxzc"> 锚;解析这些以获取每个地点的字段:
| 字段 | 锚 |
|---|---|
name |
卡片的 aria-label(完整字符串以地点名称开头) |
rating |
[role="img"][aria-label*="stars"] — aria-label 解析为 "4.8 stars" |
reviewCount |
评级旁边的文本节点,例如 "(3,174)" |
address |
卡片上的第二行文本,通常在类别后面 |
category |
第一个非评级的第二行文本 |
priceLevel |
存在时的短 $ 字符串 |
mapUrl |
a.hfpxzc[href] — 规范的地点 URL |
placeId |
从 mapUrl 解析得到,通过 !1s0x<hex>:0x<hex> 段 |
isSponsored |
卡片包含 [aria-label="Sponsored"] |
placeId 是在多个会话或图块中运行相同查询时的主要去重键。
第 6 步 — 可选:深入详细面板(browser_click + browser_get_html)
对于每个地点,代理可以点击卡片打开详细面板,然后提取更丰富的字段——完整地址、电话号码、网站、营业时间和最新评论。
jsonCopy
{
"name": "browser_click",
"arguments": {
"selector": "a.hfpxzc[href*=\"<placeId>\"]"
}
}
点击后,等待详细面板的地标渲染:
jsonCopy
{
"name": "browser_wait_for",
"arguments": {
"selector": "h1.DUwDvf"
}
}
h1.DUwDvf 是详细面板内的地点名称标题——这是面板完全绘制的最清晰信号。然后针对面板调用 browser_get_html 并进行解析:
| 字段 | 锚 |
|---|---|
placeName |
h1.DUwDvf(内部文本——如果存在则去掉嵌套 <span>) |
address |
button[data-item-id="address"] — aria-label 中的完整街道地址,格式为 "Address: <street>, <city>, …"(标签本地化) |
phone |
button[data-item-id^="phone:tel:"] — 电话号码嵌入在 data-item-id 值中(例如 phone:tel:+14252437356)并且也在 aria-label 中呈现 |
website |
a[data-item-id="authority"] — 网站是一个锚(<a>),而不是按钮;提取 href 属性 |
hours |
按日行: button[jsaction*="openhours"],每个按钮携带 aria-label="<weekday>,<open>~<close>, <copy-label>"(每个工作日一个按钮) |
reviews |
.jftiEf 评价卡片——评论者姓名、评分、正文、日期、业主回复 |
深入挖掘增加了每个地点请求的费用;仅在工作流程实际需要面板独有字段时才进行此操作。
第 7 步 — 截屏(browser_screenshot)
截屏对于视觉回归、投诉证据收集或端到端验证非常有用。代理可以在流程中的任何时刻调用 browser_screenshot 并获得一张图像。
jsonCopy
{
"name": "browser_screenshot",
"arguments": {
"fullPage": true
}
}
对于 Google 地图,整个页面的截屏包括侧边数据源和地图画布。对于仅抓取数据源的截屏,将数据源滚动回到顶部并改为截取视口大小的截图。
第 8 步 — 关闭会话(browser_close)
当代理完成操作时,调用 browser_close 释放云浏览器。该工具需要 browser_create 返回的 sessionId:
jsonCopy
{
"name": "browser_close",
"arguments": {
"sessionId": "vybp-a64d-2dqf-9vsq86"
}
}
及时释放会话有助于保持账户的并发会话数量清晰,并且在每次抓取结束时都是正确的默认操作。
超越每次查询上限的扩展
Google 地图对单次搜索的限制约为 120 个地点。对于超过该限制的查询——“曼哈顿的每家餐馆”,“加州的所有牙医”——策略是地理网格:
- 将搜索区域划分为更小的边界框。 一个社区、一个邮政编码,或一个 2 公里 × 2 公里 的正方形通常返回的结果远少于 120 个,因此每个网格都能完全耗尽。
- 每个网格运行一次查询。 可以在地图 URL 中嵌入
@lat,lng,zoom段(例如https://www.google.com/maps/search/coffee/@47.6097,-122.3331,15z)或者更改查询字符串(“皮克广场的咖啡店”→“贝尔镇的咖啡店”→“国会山的咖啡店”)。 - 通过
placeId在切片间去重。 单个地点可能会在重叠的切片中出现;从mapUrl中解析出的placeId(!1s0x<hex>:0x<hex>) 是稳定的连接键。
相同的模式由 MCP 原语组合而成——一个 browser_create + 一个 browser_goto + 滚动 + 每个切片提取,代理在对话内存中维护跨切片的去重集。
你将收到的内容
MCP 工具返回原始文本(HTML、页面文本、截图);JSON 结构是代理组装的内容。对于单次搜索和滚动过程,使用上面的发现 → 提取模板,数据结构如下:
jsonCopy
// 结构反映了代理被提示提取地点卡片时的输出。
// 字段值是示例样本。
{
"query": "西雅图派克市场的咖啡店",
"queryUrl": "https://www.google.com/maps/search/coffee+shops+in+Pike+Place+Seattle",
"resultsReturned": 15,
"results": [
{
"name": "Storyville Coffee Pike Place",
"rating": 4.8,
"reviewCount": 3174,
"address": "94 Pike St #34, Seattle, WA 98101",
"category": "咖啡店",
"priceLevel": "$$",
"mapUrl": "https://www.google.com/maps/place/Storyville+Coffee+Pike+Place/data=!4m7!3m6!1s0x54906ab2f0c61d05:0x771b2a7dce963d58!8m2!3d47.60895!4d-122.3404309",
"placeId": "0x54906ab2f0c61d05:0x771b2a7dce963d58",
"isSponsored": false,
"phone": null,
"website": null,
"hours": null
}
]
}
在大规模运行之前,有一些值得注意的关于此输出的诚实观察:
- 水合时间。 地图 SPA 分波渲染——地图画布,然后是馈送外壳,然后是卡片。针对
a.hfpxzc的browser_wait_for是提取的控制。这意味着如果代理的第一次browser_get_html只返回外壳,请求其稍等片刻并重新提取。 - 选择器稳定性。
[role="article"]、[role="feed"]、评分小部件上的aria-label字符串,以及用于规范mapUrl的a.hfpxzc[href]是最持久的锚点。类名(例如h1.DUwDvf、.jftiEf)今天有效,但在部署中会变动;将它们视为尽力而为,如果将来的抓取结果为空,请重新运行发现过程。 - 赞助位置。 赞助卡片与自然结果交错显示,并带有
[aria-label="Sponsored"]。代理应设置isSponsored而不是删除它们,以便下游消费者可以明确过滤。 - 详情面板字段是有条件的。 电话、网站和营业时间来自
button[data-item-id="…"]行,这些行并不在每个地点中存在。将它们视为可空而非必需。 - 区域和语言。 地点卡片上的用户界面文本(“营业时间”、“评论”、“网站”按钮标签)本地化为代理国家的语言。对于美国出口查询,标签为英语;对于西班牙语、法语、日语,解析器的正则表达式需要与本地化字符串匹配,否则字段将返回空值。
- 每查询上限。 每个查询大约返回 120 条结果。对于更大的地理区域,使用上述的地理网格切片模式,并通过
placeId在重叠切片之间去重。
常见问题解答
Q1:我需要使用代理访问 Google 地图吗?我可以选择地区吗?
每个云浏览器会话自动通过 Scrapeless 住宅代理路由——不需要单独配置代理以使调用工作。然而,代理区域在账户级别设置,而不是在 MCP browser_create 工具的每次调用参数中公开。需要每查询地区控制的工作流程(美国地图结果 vs 西班牙 vs 日本)应通过 scrapeless-scraping-browser CLI(它公开 --proxy-country)来操作云浏览器,或者维护多个为不同默认地区配置的 Scrapeless API 密钥。
Q2:stdio 模式和 HTTP 流式模式有什么区别?
Stdio 模式将 npx scrapeless-mcp-server 作为 MCP 客户端(Claude Desktop、Cursor 等)的子进程运行,是桌面代理的正确默认设置。HTTP 流式模式将客户端指向 https://api.scrapeless.com/mcp,是无法通过 npx 执行的云托管代理的正确默认设置。这两种模式使用相同的 Scrapeless API 密钥。
Q3:如何突破查询的 120 结果上限?
将搜索区域切分为更小的地理区域(邻里、邮政编码、经纬度边界框),并每个切片运行一个查询。使用解析出的 placeId(来自 mapUrl 的 !1s0x<hex>:0x<hex> 部分)在重叠切片之间去重。地理网格模式在“突破每查询上限”部分中有文档记录。
Q4:我可以提取地点的评论吗?
可以。在渲染馈送后,单击卡片以打开详情面板,等待 h1.DUwDvf,然后从 .jftiEf 区域提取评论卡片——标题、作者、评分、内容和日期。深入请求是按地点进行的,并增加请求成本;仅在工作流程需要评论负载时执行。
Q5:当 Google 地图更改 DOM 时会发生什么?
重新运行发现通道:请代理调用browser_get_html在相关区域,并重新识别当前稳定的锚点。[role="article"]、[role="feed"]、aria-label 字符串和 a.hfpxzc[href] 是寿命最长的;类名会随机变动。该技能的发现 → 提取模式无需代码更改即可处理此问题。
Q6:为什么我的会话有时返回“访问被拒绝”或 CAPTCHA 页面?
新的代理分配有时会落在被标记的 IP 地址上。请代理调用 browser_close 然后再调用 browser_create 以获得新的会话。之后的分配会成功。
Q9:多个代理可以共享一个 MCP 服务器吗?
每个支持 MCP 的客户端连接到其自己的服务器实例(在标准输入输出模式下)或共享的 HTTP 端点(在可流模式下)。会话由 browser_create 返回的 taskId 隔离,因此多个代理调用同一 MCP 服务器时不会共享 cookie 或滚动状态。对于高扩展性的抓取,请每个查询生成一个会话,而不是重用单个长期会话。
Q10:哪些 MCP 客户端可以使用这个?
任何支持 MCP 的客户端。 协议是合同——服务器的工具列表和调用格式在每个客户端之间是相同的。第 2 步包括 Claude Desktop、Claude Code、Cursor、OpenAI Codex CLI、Gemini CLI 和 VS Code + GitHub Copilot Chat 的设置路径;同样的 mcpServers JSON 片段也适用于基于 MCP TypeScript SDK 构建的自定义 Python 或 Node 客户端,可流式 HTTP 端点 https://api.scrapeless.com/mcp 可以与任何 HTTP 客户端配合使用。
Q11:MCP 服务器有专门的 Google 地图工具吗?
没有——服务器提供通用浏览器原语(browser_create、browser_goto、browser_wait_for、browser_get_html、browser_get_text、browser_click、browser_type、browser_press_key、browser_scroll、browser_scroll_to、browser_screenshot、browser_snapshot、browser_close),加上页面级辅助工具(scrape_html、scrape_markdown、scrape_screenshot)和 Google 数据工具(google_search、google_trends)。代理从浏览器原语构建地图抓取;相同的原语也适用于 Amazon、Home Depot、Etsy 和任何其他 JavaScript 重度网站。
Q12:为什么地图加载一个同意页面而不是搜索结果?
当云浏览器会话通过欧洲住宅代理进行路由时,Google 会在显示地图之前插入一个 consent.google.com 的过渡页面。代理应该在 browser_goto 后调用 browser_get_text,如果响应包含“同意”或“接受”按钮的标签(Accept all / Accetta tutto / Akzeptieren / Accepter),在重试导航之前对按钮调用 browser_click。第 2 步涵盖了完整的代码片段。
Q13:为什么我的会话有时会返回像 os error 10054 或 503 的瞬态连接错误?
Scrapeless 住宅代理池有时会在 browser_create 上返回短暂的分配错误。一次重试通常会成功——在生产代码中将 browser_create 放入 2-3 次尝试的重试循环中,或者简单地请代理重试一次。
Q14:我可以同时运行多少个 MCP 抓取作业?
为了可靠性,保持一个 MCP 客户端在任何时候仅有一个进行中的会话,并将调用链接在单个代理轮次内。如果需要更高的扩展性,可以运行多个 MCP 客户端(或执行访问可流 HTTP 端点的工作进程),并将每个主机的并发限制在 ≤ 3 个会话。对于纯吞吐量的批处理作业(每小时 10K+ 查询),可以通过并行工作池直接驱动 scrapeless-scraping-browser CLI;MCP 路径更适合代理主动发现和基于网格的地理覆盖。
Q15:我可以在没有 MCP 客户端的情况下运行吗?
可以。有两种路径:(1)直接通过任何 HTTP 客户端调用 https://api.scrapeless.com/mcp 的可流 HTTP 端点,并带上 x-api-token 头;(2)通过 scrapeless-scraping-browser CLI 通过 bash 驱动云浏览器。MCP 驱动的工作流程是代理提示抓取的推荐路径;CLI 是适合脚本化批处理管道的正确路径。
Q16:为什么使用标准的 /maps/search/<query> URL 而不是直接驱动搜索框?
深链接搜索 URL 使代理直接进入填充好的搜索引擎结果页面,无需点击搜索输入、输入并按回车。工具调用更少,代理点击错误控件的可能性更小,端到端运行更快。对于地点 URL 采用相同的方法:直接导航到 /maps/place/<slug>/data=!1s<placeId>,而不是在 placeId 已知时先搜索再点击。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)