🎯 Trình duyệt đám mây tùy chỉnh, chống phát hiện được hỗ trợ bởi Chromium tự phát triển, thiết kế dành cho trình thu thập dữ liệu webtác nhân AI. 👉Dùng thử ngay
Quay lại blog

Cách thu thập dữ liệu Google Maps quy mô lớn với AI agent và máy chủ Scrapeless MCP

Ethan Brown
Ethan Brown

Advanced Bot Mitigation Engineer

04-May-2026

Những điểm chính:

  • Hoạt động trong bất kỳ khách hàng nào hỗ trợ MCP. Máy chủ MCP Scrapeless cung cấp trình duyệt đám mây như một tập hợp các công cụ Giao thức Ngữ cảnh Mô hình — Claude Desktop, Claude Code, Cursor, OpenAI Codex CLI, Gemini CLI, VS Code + GitHub Copilot Chat, hoặc một khách hàng tùy chỉnh được xây dựng dựa trên MCP TypeScript SDK đều gọi chúng theo cùng một cách. Giao thức mới là phần mang trọng lượng, không phải là khách hàng. Không cần keo SDK, không cần quản lý quy trình con CLI.
  • Các phần tử trình duyệt kết hợp thành trình thu thập dữ liệu Google Maps. Máy chủ cung cấp các công cụ trình duyệt tổng quát — 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 — và tác nhân lắp ráp chúng vào quy trình tìm kiếm → cuộn → trích xuất mà Google Maps yêu cầu.
  • Hai chế độ vận chuyển. Chế độ Stdio chạy máy chủ cục bộ qua npx scrapeless-mcp-server và là mặc định phù hợp cho các khách hàng MCP trên máy tính để bàn. Chế độ có thể phát trực tiếp HTTP chỉ định khách hàng đến https://api.scrapeless.com/mcp và là mặc định phù hợp cho các tác nhân được lưu trữ trên đám mây.
  • Kết xuất đám mây cộng với proxy dân cư. Google Maps là một SPA nặng về JavaScript mà tải kết quả một cách lười biếng dưới dạng luồng. Scrapeless Scraping Browser xử lý kết xuất JS, lưu lượng ra proxy dân cư, và lớp nhận dạng chống phát hiện trong mọi phiên — tác nhân chỉ cần điều khiển trang. Các phiên được phân bổ thông qua khu vực proxy mà tài khoản Scrapeless được cấu hình; không có vượt qua khu vực theo cuộc gọi nào được tiết lộ qua giao diện công cụ MCP ngày hôm nay.
  • Giới hạn danh sách kết quả theo truy vấn. Google Maps hiển thị tối đa 120 kết quả cho mỗi truy vấn trong luồng bên. Vượt qua điều đó, chiến lược là lưới địa lý: chia khu vực tìm kiếm thành các hộp giới hạn nhỏ hơn, chạy một truy vấn cho mỗi ô, và loại bỏ trùng lặp theo id địa điểm.
  • Miễn phí để bắt đầu. Các tài khoản Scrapeless mới bao gồm thời gian chạy Scraping Browser miễn phí — đăng ký tại Scrapeless.

Giới thiệu: một con đường gốc MCP đến dữ liệu Google Maps

Google Maps là một trong những tập dữ liệu kinh doanh công khai phong phú nhất trên web mở — tên, địa chỉ, đánh giá, số lượng đánh giá, giờ mở cửa, liên kết ảnh, thẻ danh mục, chi tiết liên hệ, và một id địa điểm ổn định cho mỗi mục. Đối với các đội SEO địa phương, quy trình tạo ra khách hàng tiềm năng, phân tích bất động sản, và lập bản đồ vị trí đối thủ, tập dữ liệu đó là nền tảng của quy trình làm việc.

Trang web chính nó rất khó để điều khiển mà không có một trình duyệt thực sự. Chế độ xem bản đồ tải SDK của riêng nó, bảng bên phân trang thông qua việc tải lười biếng khi luồng cuộn, các bảng chi tiết cá nhân mở ra qua các cú nhấp chuột của người dùng, và số lượng kết quả giới hạn khoảng 120 cho mỗi truy vấn. Việc thu thập dữ liệu thuần HTTP trả về shell JS; dữ liệu nằm sau DOM đã được kết xuất.

Bài viết này hướng dẫn cách sử dụng Máy chủ MCP Scrapeless với bất kỳ khách hàng biết về MCP — Claude Desktop, Claude Code, Cursor, OpenAI Codex CLI, Gemini CLI, hoặc một khách hàng tùy chỉnh được xây dựng dựa trên MCP TypeScript SDK — để thu thập dữ liệu Google Maps từ đầu đến cuối. Máy chủ bao bọc Scrapeless Scraping Browser — một trình duyệt đám mây sẵn sàng cho tác nhân — như một tập hợp các công cụ MCP, vì vậy tác nhân gọi browser_create / browser_goto / browser_scroll / browser_get_html trực tiếp qua giao thức thay vì gọi ra một CLI hoặc lắp ráp một SDK. Trình duyệt đám mây xử lý việc kết xuất, các proxy, và lớp chống phát hiện; tác nhân xử lý mẫu phát hiện → trích xuất.

Để có cùng một mục tiêu thông qua một giao diện tích hợp khác, xem bài viết về tác nhân LangChain hoặc, đối với phiên bản bash CLI, bài viết toàn diện hơn về các công cụ tìm kiếm.


Những gì bạn có thể làm với nó

  • Tạo khách hàng tiềm năng địa phương. Nhận tất cả nha sĩ, thợ sửa ống nước, hoặc quán cà phê trong một thành phố mục tiêu với tên, địa chỉ, số điện thoại, trang web, giờ làm việc, đánh giá, và số lượng đánh giá.
  • Phân tích cạnh tranh SEO địa phương. Theo dõi xếp hạng vị trí đối thủ trên các truy vấn từ khóa danh mục và các danh sách xung quanh trên cùng một SERP.
  • Xây dựng tập dữ liệu bất động sản và điểm thú vị (POI). Xây dựng bảng điểm thú vị phân loại — nhà hàng theo ẩm thực, chuỗi bán lẻ theo khu vực, dịch vụ công cộng theo mã bưu điện — được làm mới trên cơ sở tuần tự.
  • Theo dõi danh tiếng. Ghi lại đánh giá theo vị trí, số lượng đánh giá, và tốc độ đánh giá trên một thương hiệu đa vị trí để xác định các vị trí vượt trội.
  • Nghiên cứu thị trường. Vẽ bản đồ mật độ và sự pha trộn danh mục của doanh nghiệp nhỏ trong một khu vực mục tiêu để ước tính độ bão hòa thị trường.
  • Thông tin về hình ảnh và giá cả. Chụp ảnh màn hình của bảng địa điểm để thực hiện kiểm tra hình ảnh, hoặc lấy chỉ số cấp độ giá ($, $$, $$$) cho mỗi danh sách.

Tại sao lại là Scrapeless Scraping Browser

Scrapeless Scraping Browser là một trình duyệt đám mây tùy chỉnh, chống phát hiện, được thiết kế cho các cỗ máy thu thập dữ liệu web và các đại lý AI. Đối với Google Maps cụ thể, nó mang lại:

  • Kết xuất JavaScript phía đám mây để SDK bản đồ, nguồn cấp bên, tải lười biếng dựa trên cuộn và bảng chi tiết địa điểm đều được điền trước khi trích xuất.
  • Proxy dân cư ở hơn 195 quốc gia để các truy vấn theo vị trí địa lý trả về danh sách mà người dùng địa phương sẽ nhìn thấy — điều này rất quan trọng vì kết quả Google Maps thay đổi theo khu vực xuất phát.
  • Chống phát hiện dấu vân tay trên mỗi phiên làm việc để trang được kết xuất giống hệt như lưu lượng truy cập tự nhiên trong các phiên cuộn dài.
  • Duy trì phiên làm việc thông qua ID nhiệm vụ browser_create; các lệnh gọi công cụ browser_* tiếp theo trong cùng một đại lý sẽ tái sử dụng cùng một trình duyệt đám mây, giữ cho cookie, vị trí cuộn và lịch sử điều hướng nhất quán.
  • Một bề mặt MCP duy nhất — mọi thao tác mà đại lý cần để điều khiển Bản đồ (browser_goto, browser_wait_for, browser_scroll, browser_click, browser_get_html, browser_get_text, browser_screenshot) chỉ cần một lệnh gọi công cụ.

Nhận khóa API của bạn trên gói miễn phí tại Scrapeless. Bề mặt công cụ MCP đầy đủ được tài liệu hóa tại github.com/scrapeless-ai/scrapeless-mcp-server.


Điều kiện tiên quyết

  • Bất kỳ khách hàng nào hỗ trợ MCP. Claude Desktop (claude.com/download), Claude Code, Cursor, OpenAI Codex CLI, Gemini CLI, VS Code + GitHub Copilot Chat, hoặc một khách hàng tùy chỉnh được xây dựng dựa trên MCP TypeScript SDK — giao thức là yếu tố vững chắc, không phải là khách hàng.
  • Node.js phiên bản 18 trở lên (cho chế độ truyền tải stdio).
  • Tài khoản Scrapeless và khóa API — đăng ký tại Scrapeless.
  • Kiến thức cơ bản về cách chỉnh sửa tệp cấu hình MCP của khách hàng của bạn.

Cài đặt

Máy chủ MCP Scrapeless được phát hành dưới dạng gói npm scrapeless-mcp-server và có thể được gọi từ bất kỳ khách hàng nào hỗ trợ Giao thức Ngữ cảnh Mô hình. Bốn bước thiết lập dưới đây cho thấy lộ trình cài đặt cho các khách hàng phổ biến nhất (Claude Desktop, Claude Code, Cursor, OpenAI Codex CLI, Gemini CLI), nhưng đoạn mã JSON tự nó có thể di chuyển — hãy chèn nó vào bất kỳ khách hàng nào mà nhóm bạn đã sử dụng và các lệnh gọi công cụ giống nhau sẽ hoạt động.

1. Nhận khóa API Scrapeless của bạn

Đăng ký tại Scrapeless, mở bảng điều khiển, và từ Cài đặt → Quản lý Khóa API tạo một khóa. Sao chép giá trị — nó sẽ vào trong cấu hình MCP ở bước 2.

Nhận khóa API của bạn trên gói miễn phí bằng cách đăng ký trên Scrapeless và tham gia cộng đồng chính thức:
Cộng đồng Chính thức của Scrapeless trên Discord
Cộng đồng Chính thức của Scrapeless trên Telegram

2. Thêm máy chủ MCP vào khách hàng của bạn (chế độ stdio)

Vị trí tệp cấu hình phụ thuộc vào khách hàng:

Claude Desktop (ứng dụng máy tính để bàn từ claude.com/download):

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Claude Code (CLI terminal):

  • Tất cả các nền tảng: ~/.claude.json
  • Hoặc sử dụng lệnh phụ claude mcp add thay vì chỉnh sửa tệp bằng tay:
    bash Copy
    claude mcp add scrapeless --scope user --transport stdio \
      --env "SCRAPELESS_KEY=YOUR_SCRAPELESS_KEY" \
      -- npx -y scrapeless-mcp-server

Cursor: chỉnh sửa ~/.cursor/mcp.json (hoặc sử dụng Thiết lập của Cursor → Giao diện MCP). Cùng cấu trúc JSON như đoạn mã dưới đây.

OpenAI Codex CLI: Codex đọc các máy chủ MCP từ ~/.codex/config.toml và cũng cung cấp một trợ lý codex mcp. Lệnh cài đặt stdio là:

bash Copy
codex mcp add scrapeless \
  --env "SCRAPELESS_KEY=YOUR_SCRAPELESS_KEY" \
  -- npx -y scrapeless-mcp-server

TOML tương đương là:

toml Copy
[mcp_servers.scrapeless]
command = "npx"
args = ["-y", "scrapeless-mcp-server"]

[mcp_servers.scrapeless.env]
SCRAPELESS_KEY = "YOUR_SCRAPELESS_KEY"

Sau khi chỉnh sửa tệp, khởi động lại Codex và xác nhận mục nhập với codex mcp list --json. Codex rất nghiêm ngặt về cấu trúc stdio MCP: quá trình máy chủ chỉ được phép ghi các thông điệp JSON-RPC vào stdout. Nếu Codex báo cáo handshaking with MCP server failed, initialize response, hoặc connection closed, hãy kiểm tra xem máy chủ có in một dòng log khởi động vào stdout trước khi gửi phản hồi JSON-RPC không. Nâng cấp lên một phiên bản máy chủ đã được sửa lỗi hoặc chạy máy chủ phía sau một bộ lọc stdio nhỏ để chuyển hướng các dòng stdout không phải JSON sang stderr.
Sử dụng chế độ stdio làm đường dẫn Codex mặc định. Hiện tại, các bản dựng Codex CLI cung cấp codex mcp add --url cho các máy chủ HTTP có thể stream, nhưng tùy chọn xác thực tích hợp của trợ giúp dựa trên token mang, trong khi điểm cuối MCP được lưu trữ của Scrapeless mong đợi tiêu đề x-api-token. Chỉ sử dụng chế độ HTTP từ Codex nếu phiên bản/cấu hình Codex của bạn hỗ trợ các tiêu đề HTTP tùy chỉnh cho các máy chủ MCP.

Gemini CLI: Gemini hỗ trợ các máy chủ MCP thông qua mcpServers trong settings.json, cộng với một trợ giúp gemini mcp. Gemini CLI hiện tại yêu cầu Node.js 20 hoặc mới hơn. Để cài đặt stdio cho toàn bộ người dùng, hãy chạy:

bash Copy
gemini mcp add -s user \
  -e SCRAPELESS_KEY=YOUR_SCRAPELESS_KEY \
  scrapeless npx -y scrapeless-mcp-server

Hoặc chỉnh sửa trực tiếp ~/.gemini/settings.json:

json Copy
{
  "mcpServers": {
    "scrapeless": {
      "command": "npx",
      "args": ["-y", "scrapeless-mcp-server"],
      "env": {
        "SCRAPELESS_KEY": "YOUR_SCRAPELESS_KEY"
      }
    }
  }
}

Sử dụng .gemini/settings.json thay vào đó để cấu hình theo phạm vi dự án. Xác nhận với gemini mcp list (hoặc gemini --debug mcp list nếu shell không tương tác của bạn không in bảng), hoặc khởi động Gemini và chạy /mcp để xem trạng thái kết nối và các công cụ đã phát hiện.

VS Code + GitHub Copilot Chat: đoạn mã mcpServers tương tự này đi vào cài đặt MCP ở cấp độ workspace hoặc người dùng; tham khảo tài liệu MCP của GitHub Copilot Chat để biết đường dẫn hoạt động.

Thêm mục máy chủ Scrapeless dưới mcpServers:

json Copy
{
  "mcpServers": {
    "scrapeless": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "scrapeless-mcp-server"],
      "env": {
        "SCRAPELESS_KEY": "YOUR_SCRAPELESS_KEY"
      }
    }
  }
}

Thay thế YOUR_SCRAPELESS_KEY bằng key từ bước 1. Khởi động lại client để nhận diện máy chủ mới. Trong lần chạy đầu tiên, npx -y scrapeless-mcp-server tải xuống gói và khởi động máy chủ qua stdio — không cần lệnh cài đặt riêng. Sau khi khởi động lại, bảng điều khiển MCP của client nên hiển thị scrapeless cùng với bất kỳ máy chủ nào khác đã kết nối.

3. Hoặc sử dụng chế độ streamable HTTP (đại lý được lưu trữ trên đám mây)

Đối với các đại lý chạy từ xa — một máy chủ Cursor được lưu trữ, một CI runner, một client MCP tùy chỉnh chạy trong một container — hãy chỉ định client vào điểm cuối MCP được lưu trữ của Scrapeless thay vì chạy npx cục bộ:

json Copy
{
  "mcpServers": {
    "Scrapeless MCP Server": {
      "type": "streamable-http",
      "url": "https://api.scrapeless.com/mcp",
      "headers": {
        "x-api-token": "YOUR_SCRAPELESS_KEY"
      },
      "disabled": false,
      "alwaysAllow": []
    }
  }
}

Cùng một YOUR_SCRAPELESS_KEY hoạt động ở cả hai chế độ. Vận chuyển HTTP là mặc định đúng khi nhị phân stdio không thể chạy cùng với đại lý (các sandbox CI, các runner đại lý được lưu trữ).

Đối với Gemini CLI, trợ giúp HTTP và dạng JSON như sau:

bash Copy
gemini mcp add -s user -t http \
  -H "x-api-token: YOUR_SCRAPELESS_KEY" \
  scrapeless https://api.scrapeless.com/mcp
json Copy
{
  "mcpServers": {
    "scrapeless": {
      "httpUrl": "https://api.scrapeless.com/mcp",
      "headers": {
        "x-api-token": "YOUR_SCRAPELESS_KEY"
      }
    }
  }
}

4. Xác minh máy chủ MCP đã được kết nối

Trước khi bắt đầu quét bản đồ thực tế, hãy thử nghiệm cài đặt bằng một lời nhắc:

"Sử dụng máy chủ Scrapeless MCP để mở https://example.com và cho tôi biết tiêu đề trang."

Đại lý nên gọi browser_create để mở phiên, sau đó browser_goto để điều hướng, sau đó browser_get_text (hoặc browser_get_html) và trả lời với "Example Domain". Nếu điều đó quay lại, máy chủ MCP đã được tải, key API đã được thiết lập và trình duyệt đám mây có thể truy cập được.

Nếu thất bại:

Triệu chứng Nguyên nhân có thể Cách sửa
"Tôi không thấy công cụ Scrapeless" Máy chủ MCP không được tải bởi client Kiểm tra lại đường dẫn tệp cấu hình, khởi động lại client, tìm máy chủ trong chỉ báo MCP của client
Xác thực không thành công / 401 Key API không được thiết lập hoặc đã hết hạn Sao chép lại key từ bảng điều khiển, dán vào tệp cấu hình, khởi động lại client
npx treo trong lần chạy đầu tiên Mạng chậm hoặc thời gian chờ đăng ký Chạy npx -y scrapeless-mcp-server một lần trong terminal để lưu cache gói, sau đó khởi động lại client
Codex nói initialize response hoặc connection closed trong quá trình khởi động MCP Máy chủ stdio đã ghi văn bản không phải JSON vào stdout trước khi bắt tay JSON-RPC của MCP Nâng cấp máy chủ hoặc bọc nó để chỉ các dòng JSON-RPC đến stdout và lịch sử ghi vào stderr
Lời gọi công cụ trả về HTML Access Denied Hồ bơi proxy hoặc thách thức chống bot trên một phân bổ mới Yêu cầu đại lý thử lại — browser_close sau đó browser_create tạo ra một phiên mới

Cách bạn thực sự sử dụng điều này: nhắc nhở đại lý của bạn

Sau khi cài đặt, bạn có thể quét Google Maps bằng cách nói chuyện với đại lý của bạn — không bằng cách mã hóa thủ công các lời gọi công cụ. Máy chủ MCP tiết lộ trình duyệt đám mây dưới dạng danh sách công cụ có thể khám phá; đại lý đọc mô tả công cụ và kết hợp chúng thành đúng trình tự dựa trên lời nhắc.

Các lời nhắc bạn có thể dán

| Bạn nói với đại lý của bạn | Những gì bạn nhận lại |
| "Lấy 30 quán cà phê hàng đầu ở Pike Place, Seattle từ Google Maps. Trả lại JSON với tên, xếp hạng, số lượng đánh giá, địa chỉ." | Một bản ghi JSON cho mỗi địa điểm với các trường yêu cầu |
| "Liệt kê tất cả nha sĩ ở mã bưu điện 90015 với số điện thoại, trang web và giờ mở cửa." | JSON theo từng địa điểm với dữ liệu liên hệ + giờ mở cửa |
| "Tìm kiếm Google Maps cho 'nhà hàng sushi gần Cầu Brooklyn', cuộn xuống cuối danh sách, trả lại mọi thứ." | Đến khoảng ~120 địa điểm, không trùng lặp theo tên + địa chỉ |
| "Đối với mỗi kết quả, cũng nhấn vào bảng chi tiết và lấy URL trang web và địa chỉ đầy đủ." | JSON theo từng địa điểm được làm phong phú với các trường bảng chi tiết |
| "Chụp màn hình trang kết quả tìm kiếm sau khi cuộn." | Màn hình chụp + JSON đã trích xuất |
| "Tìm các nhà hàng Ý ở 'San Francisco'. Lọc ra những nhà hàng có xếp hạng ≥ 4.5 và ít nhất 200 đánh giá." | Danh sách địa điểm đã lọc |
| "Chạy cùng một truy vấn từ địa chỉ IP ở Madrid — trả về các kết quả Maps như người dùng Tây Ban Nha sẽ thấy." | Kết quả chú ý đến địa phương (Các tuyến không scrap qua một proxy dân cư ở Tây Ban Nha) |
| "Đối với địa điểm có tên 'Storyville Coffee Pike Place', mở bảng địa điểm và lấy 10 đánh giá mới nhất." | Tải trọng đánh giá của bảng chi tiết |
Công cụ browser_create cấp phát một trình duyệt đám mây mới và trả về một id phiên mà tác nhân dùng cho toàn bộ quy trình tiếp theo. Phiên là đơn vị trạng thái - cookies, vị trí cuộn, và lịch sử điều hướng tất cả đều nằm bên trong nó.

Gọi công cụ (những gì tác nhân gửi qua MCP):

json Copy
{
  "name": "browser_create",
  "arguments": {}
}

Công cụ trả về một payload như New browser session created with ID: vybp-a64d-2dqf-9vsq86. Các cuộc gọi browser_* tiếp theo trong cùng một tác nhân sẽ tự động tái sử dụng phiên hoạt động; việc truyền id đã trả về dưới dạng sessionId được hỗ trợ nhưng không bắt buộc.

Khu vực proxy được thiết lập bởi cấu hình tài khoản Scrapeless — công cụ browser_create của MCP không tiết lộ tham số proxyCountry theo từng cuộc gọi. Đối với các quy trình cần kiểm soát khu vực theo từng truy vấn (kết quả bản đồ Mỹ so với ES so với JP), sử dụng CLI scrapeless-scraping-browser trực tiếp với --proxy-country, hoặc chạy nhiều khóa API Scrapeless được cấu hình cho các khu vực khác nhau.

Nếu cuộc gọi trả về lỗi kết nối tạm thời, hãy yêu cầu tác nhân thử lại một lần. Hồ bơi proxy đôi khi không trả về địa chỉ IP dân cư nào có sẵn vào thời điểm cấp phát; một browser_create mới sẽ thành công ở lần thử tiếp theo.


Bước 2 — Điều hướng đến URL tìm kiếm Bản đồ (browser_goto)

Google Maps cung cấp một mẫu URL liên kết sâu để tìm kiếm: https://www.google.com/maps/search/<query>. Mã hóa URL cho truy vấn, và trang sẽ tải với nguồn bên cạnh được làm đầy cho tìm kiếm đó.

json Copy
{
  "name": "browser_goto",
  "arguments": {
    "url": "https://www.google.com/maps/search/coffee+shops+in+Pike+Place+Seattle"
  }
}

Dạng URL đưa tác nhân trực tiếp đến một SERP đã được làm đầy mà không cần điều khiển ô tìm kiếm, giúp quy trình ngắn hơn và giảm diện tích bề mặt mà tác nhân có thể nhấp vào điều khiển sai.

Xử lý tường đồng ý. Khi trình duyệt đám mây đi qua một proxy dân cư Châu Âu, Google ngắt quãng điều hướng với một màn hình đồng ý tại consent.google.com trước khi hiển thị Bản đồ. Tác nhân nên gọi browser_get_text sau browser_goto và kiểm tra xem phản hồi có chứa "đồng ý" hoặc "Chấp nhận tất cả" / các phiên bản địa phương tương đương (Accetta tutto, Akzeptieren, Accepter) hay không. Nếu có, hãy điều khiển browser_click vào nút Chấp nhận - các nhãn có thể truy cập hoạt động trên các ngôn ngữ địa phương:

json Copy
{
  "name": "browser_click",
  "arguments": {
    "selector": "button[aria-label*='Accept' i], form[action*='consent'] button:last-of-type"
  }
}

Sau khi nhấp, lặp lại browser_goto để đến trang Bản đồ chính. Các quy trình chạy qua một khu vực proxy Mỹ thường không gặp phải tường này.


Bước 3 — Chờ nguồn thông tin hiển thị (browser_wait_for)

SPA trên Bản đồ được tô điểm theo từng đợt: trước tiên là canvas bản đồ, sau đó là màn hình nguồn bên cạnh, sau đó là thẻ địa điểm. Hãy chờ theo một mốc thẻ địa điểm trước khi trích xuất, nếu không vùng kết quả sẽ trống.

json Copy
{
  "name": "browser_wait_for",
  "arguments": {
    "selector": "a.hfpxzc"
  }
}

a.hfpxzc là neo liên kết địa điểm chính - một cho mỗi thẻ hữu cơ trong nguồn bên cạnh, với tên địa điểm trong aria-label và URL chính thức /maps/place/<slug>/data=!1s<placeId> trong href. Đây là tín hiệu đáng tin cậy nhất cho biết các thẻ đã được hiển thị, vì mốc bài viết đôi khi bị chậm lại so với các neo liên kết trong quá trình làm đầy.

Nếu thời gian chờ hết, trang có thể đã rơi vào một trang chuyển tiếp (hiếm) hoặc nguồn thông tin thực sự trống cho truy vấn này. Hãy yêu cầu tác nhân gọi browser_get_text để xuất ra văn bản trang visible để xác định trường hợp nào.


Bước 4 — Cuộn nguồn để tải thêm kết quả (browser_scroll, browser_press_key)

Nguồn bên cạnh ban đầu hiển thị khoảng 10-20 thẻ. Các lô tiếp theo sẽ được tải lén khi nguồn cuộn, tối đa cho mỗi truy vấn khoảng 120 địa điểm.

Máy chủ MCP cung cấp hai nguyên tắc cuộn:

  • browser_scroll — cuộn trang, không cần tham số nào (nó hoạt động trên tài liệu hoạt động).
  • browser_scroll_to — cuộn đến tọa độ pixel tuyệt đối. Tham số yêu cầu: {x, y} số.
json Copy
{
  "name": "browser_scroll",
  "arguments": {}
}

Đối với Google Maps, nguồn bên cạnh là một container có thể cuộn của riêng nó thay vì trang chính, vì vậy một browser_scroll đơn giản có thể không tiến hành tải lén. Mô hình đáng tin cậy là trước tiên tập trung vào nguồn bằng browser_click vào bất kỳ thẻ nào đã được hiển thị, sau đó kích hoạt cuộn bằng bàn phím với browser_press_key:

json Copy
{
  "name": "browser_click",
  "arguments": { "selector": "a.hfpxzc:first-of-type" }
}
json Copy
{
  "name": "browser_press_key",
  "arguments": { "key": "End" }
}

Một quy trình điển hình: nhấp vào thẻ đầu tiên, sau đó browser_press_key với "End" hoặc "PageDown" từ ba đến năm lần, với một browser_wait 1500 ms giữa các lần nhấn phím để việc tải lén hoàn tất trước khi lần nhấn tiếp theo diễn ra.
Đối với những lần kéo sâu, tác nhân nên theo dõi số lượng thẻ sau mỗi lần cuộn: khi hai cuộc gọi browser_get_html liên tiếp trả về cùng một số lượng, nguồn cấp đã đạt giới hạn theo truy vấn và các lần cuộn sau không thêm kết quả.


Bước 5 — Trích xuất thẻ địa điểm (browser_get_html)

Khi nguồn cấp đã hiển thị số thẻ mong muốn, hãy lấy toàn bộ HTML và để tác nhân phân tích.

json Copy
{
  "name": "browser_get_html",
  "arguments": {}
}

browser_get_html trả về toàn bộ DOM đã được hiển thị như một tải trọng văn bản duy nhất — không có đối số chọn theo vùng; tác nhân cắt HTML trong bộ nhớ sau khi phản hồi đến. Mỗi thẻ hữu cơ xuất hiện như một <a class="hfpxzc"> liên kết; phân tích chúng để lấy các trường theo địa điểm:

Trường Liên kết
name aria-label của thẻ (chuỗi đầy đủ bắt đầu bằng tên địa điểm)
rating [role="img"][aria-label*="stars"]aria-label phân tích là "4.8 stars"
reviewCount Nút văn bản bên cạnh đánh giá, ví dụ "(3,174)"
address Một dòng văn bản phụ trên thẻ, thường là sau loại
category Dòng văn bản phụ không phải là đánh giá đầu tiên
priceLevel Một mã ngắn của ký tự $ khi có mặt
mapUrl a.hfpxzc[href] — URL địa điểm chuẩn
placeId Được phân tích từ mapUrl thông qua đoạn !1s0x<hex>:0x<hex>
isSponsored Thẻ chứa [aria-label="Sponsored"]

placeId là khóa dedupe chịu tải khi chạy cùng một truy vấn trên nhiều phiên hoặc ô.


Bước 6 — Tùy chọn: đi sâu vào bảng chi tiết (browser_click + browser_get_html)

Đối với mỗi địa điểm, tác nhân có thể nhấp thẻ để mở bảng chi tiết, sau đó trích xuất các trường phong phú hơn — địa chỉ đầy đủ, số điện thoại, trang web, giờ mở cửa, và các đánh giá gần đây.

json Copy
{
  "name": "browser_click",
  "arguments": {
    "selector": "a.hfpxzc[href*=\"<placeId>\"]"
  }
}

Sau khi nhấp, chờ lâu đài bảng chi tiết hiển thị:

json Copy
{
  "name": "browser_wait_for",
  "arguments": {
    "selector": "h1.DUwDvf"
  }
}

h1.DUwDvf là tiêu đề tên địa điểm bên trong bảng chi tiết — đây là tín hiệu rõ ràng nhất rằng bảng đã hoàn toàn được hiển thị. Sau đó gọi browser_get_html đối với bảng và phân tích:

Trường Liên kết
placeName h1.DUwDvf (nội dung bên trong — loại bỏ các <span> lồng nếu có)
address button[data-item-id="address"] — địa chỉ đường phố đầy đủ trong aria-label, định dạng "Address: <street>, <city>, …" (nhãn đã được địa phương hóa)
phone button[data-item-id^="phone:tel:"] — số điện thoại được nhúng trong giá trị data-item-id (ví dụ phone:tel:+14252437356) và cũng được hiển thị trong aria-label
website a[data-item-id="authority"] — trang web là một thẻ liên kết (<a>), không phải nút; lấy thuộc tính href
hours Các dòng theo ngày: button[jsaction*="openhours"], mỗi dòng mang aria-label="<weekday>,<open>~<close>, <copy-label>" (một nút cho mỗi ngày trong tuần)
reviews Thẻ đánh giá .jftiEf — tên người đánh giá, đánh giá, nội dung, ngày, phản hồi của chủ sở hữu

Đi sâu vào bảng chi tiết làm tăng chi phí yêu cầu theo địa điểm; chỉ nên thực hiện khi quy trình thực sự cần các trường chỉ có trong bảng.


Bước 7 — Chụp ảnh màn hình (browser_screenshot)

Một bức ảnh màn hình hữu ích cho việc hồi quy hình ảnh, thu thập chứng cứ, hoặc xác minh cuối cùng. Tác nhân gọi browser_screenshot ở bất kỳ điểm nào trong quy trình và nhận lại một bức ảnh.

json Copy
{
  "name": "browser_screenshot",
  "arguments": {
    "fullPage": true
  }
}

Đối với Google Maps, ảnh màn hình toàn trang bao gồm cả nguồn cấp bên và canvas bản đồ. Đối với ảnh màn hình chỉ có nguồn cấp, hãy cuộn lại trên nguồn cấp và chụp ảnh màn hình có kích thước viewport thay vì.


Bước 8 — Đóng phiên (browser_close)

Khi tác nhân đã hoàn thành, nó gọi browser_close để giải phóng trình duyệt đám mây. Công cụ yêu cầu sessionId được trả về bởi browser_create:

json Copy
{
  "name": "browser_close",
  "arguments": {
    "sessionId": "vybp-a64d-2dqf-9vsq86"
  }
}

Giải phóng phiên kịp thời giữ cho số lượng phiên đồng thời của tài khoản sạch sẽ và là mặc định đúng vào cuối mỗi lần quét.


Mở rộng vượt quá giới hạn theo truy vấn

Google Maps giới hạn một tìm kiếm ở khoảng 120 địa điểm. Đối với các truy vấn vượt quá giới hạn đó — "mọi nhà hàng ở Manhattan", "tất cả các nha sĩ ở California" — chiến lược là một lưới địa lý:

  1. Chia nhỏ khu vực tìm kiếm thành các hộp bao nhỏ hơn. Một khu dân cư, một mã bưu điện, hoặc một hình vuông 2 km × 2 km thường trả về ít hơn 120 kết quả, vì vậy mỗi ô sẽ được sử dụng hoàn toàn.
  2. Chạy một truy vấn cho mỗi ô. Hoặc nhúng một phân đoạn @lat,lng,zoom trong URL Maps (ví dụ https://www.google.com/maps/search/coffee/@47.6097,-122.3331,15z) hoặc thay đổi chuỗi truy vấn ("quán cà phê ở Pike Place" → "quán cà phê ở Belltown" → "quán cà phê ở Capitol Hill").
  3. Loại bỏ trùng lặp giữa các ô bằng placeId. Một địa điểm có thể xuất hiện trên các ô chồng chéo; placeId được phân tích từ mapUrl (!1s0x<hex>:0x<hex>) là khóa kết nối ổn định.

Mô hình này được tạo thành từ các phần tử MCP — một browser_create + một browser_goto + cuộn + trích xuất cho mỗi ô, với đại lý duy trì bộ loại bỏ trùng lặp giữa các ô trong bộ nhớ cuộc trò chuyện.


Những gì bạn nhận lại

Công cụ MCP trả về văn bản thô (HTML, văn bản trang, ảnh chụp màn hình); hình dạng JSON là bất kỳ thứ gì mà đại lý lắp ráp. Đối với một lần tìm kiếm và cuộn đơn lẻ với mẫu khám phá → trích xuất ở trên, sơ đồ trông như thế này:

json Copy
// Sơ đồ phản ánh những gì đại lý phát ra khi được yêu cầu trích xuất thẻ địa điểm.
// Giá trị trường là mẫu minh họa.
{
  "query": "cà phê trong Pike Place Seattle",
  "queryUrl": "https://www.google.com/maps/search/cà+phê+trong+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": "Quán cà phê",
      "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
    }
  ]
}

Một vài quan sát trung thực về đầu ra này, đáng để biết trước khi chạy quy mô lớn:

  • Thời gian hydrat hóa. Bản đồ SPA được render theo từng đợt — canvas bản đồ, sau đó là shell feed, sau đó là thẻ. Một browser_wait_for chống lại a.hfpxzc là điều kiện để bắt đầu trích xuất. Nếu lần đầu tiên browser_get_html của đại lý chỉ trả về shell, hãy yêu cầu nó chờ thêm một chút và trích xuất lại.
  • Độ ổn định của bộ chọn. [role="article"], [role="feed"], chuỗi aria-label trên các widget đánh giá, và a.hfpxzc[href] cho mapUrl chính thức là những điểm tựa lâu dài nhất. Tên lớp (ví dụ: h1.DUwDvf, .jftiEf) vẫn hoạt động hôm nay nhưng có thể thay đổi qua các lần triển khai; hãy coi chúng là nỗ lực tốt nhất và chạy lại một lần khám phá nếu lần lấy sau không có dữ liệu.
  • Vị trí được tài trợ. Các thẻ được tài trợ lồng ghép với các kết quả tự nhiên và mang [aria-label="Sponsored"]. Đại lý nên đặt isSponsored thay vì bỏ qua chúng, để các người sử dụng sau có thể lọc rõ ràng.
  • Các trường trong bảng chi tiết là có điều kiện. Điện thoại, website và giờ mở cửa đến từ các hàng button[data-item-id="…"] không tồn tại ở mọi địa điểm. Hãy coi chúng là có thể bỏ trống thay vì bắt buộc.
  • Ngôn ngữ và khu vực. Văn bản giao diện trên các thẻ địa điểm (nhãn nút "hours", "reviews", "website") sẽ được địa phương hóa theo ngôn ngữ của quốc gia proxy. Đối với các truy vấn từ Mỹ, nhãn là tiếng Anh; đối với ES, FR, JP, regex của bộ phân tích cần khớp với các chuỗi đã được địa phương hóa hoặc trường sẽ trở lại null.
  • Giới hạn theo truy vấn. Khoảng 120 kết quả cho mỗi truy vấn trong feed bên. Đối với các khu vực lớn hơn, hãy sử dụng mô hình lát địa lý trên và loại bỏ trùng lặp bằng placeId.

FAQ

Q1: Tôi có cần một proxy cho Google Maps không, và có thể chọn khu vực không?
Mỗi phiên duyệt đám mây đều tự động chuyển qua proxy nhà ở Scrapeless — không cần cấu hình proxy riêng cho cuộc gọi này hoạt động. Tuy nhiên, vùng proxy được thiết lập ở cấp tài khoản và không được đưa ra như một tham số theo cuộc gọi trên công cụ browser_create của MCP. Các quy trình cần kiểm soát khu vực theo truy vấn (kết quả bản đồ Mỹ so với ES so với JP) nên điều khiển trình duyệt đám mây thông qua scrapeless-scraping-browser CLI (có --proxy-country) hoặc duy trì nhiều khóa API Scrapeless được cấu hình cho các vùng mặc định khác nhau.

Q2: Sự khác nhau giữa chế độ stdio và chế độ có thể truyền tải HTTP là gì?
Chế độ stdio chạy npx scrapeless-mcp-server như một tiến trình con của khách hàng MCP (Claude Desktop, Cursor, v.v.) và là mặc định đúng cho các đại lý desktop. Chế độ có thể truyền tải HTTP định hướng khách hàng đến https://api.scrapeless.com/mcp và là mặc định đúng cho các đại lý lưu trữ đám mây không thể gọi đến npx. Cả hai chế độ đều sử dụng cùng một khóa API Scrapeless.

Q3: Làm thế nào tôi có thể vượt qua giới hạn 120 kết quả cho một truy vấn?
Chia khu vực tìm kiếm thành các khu vực nhỏ hơn (khu phố, mã bưu điện, hộp giới hạn lat/lng) và thực hiện một truy vấn cho mỗi ô. Sử dụng placeId được phân tích (từ đoạn !1s0x<hex>:0x<hex> trong mapUrl) để loại bỏ trùng lặp giữa các ô chồng chéo. Mô hình geo-grid được tài liệu hóa trong phần Mở rộng vượt giới hạn theo truy vấn ở trên.

Q4: Tôi có thể trích xuất đánh giá từ một địa điểm không?
Có. Sau khi feed được render, nhấp vào thẻ để mở bảng chi tiết, chờ h1.DUwDvf, sau đó trích xuất các thẻ đánh giá từ vùng .jftiEf — tiêu đề, tác giả, đánh giá, nội dung và ngày tháng. Việc khoan sâu là theo từng địa điểm và làm tăng chi phí yêu cầu; chỉ nên thực hiện khi quy trình làm việc cần tải trọng đánh giá.

Q5: Điều gì xảy ra khi Google Maps thay đổi DOM?
Chạy lại một bước khám phá: yêu cầu đại lý gọi browser_get_html trên khu vực liên quan và xác định lại các điểm mỏ neo ổn định hiện tại. [role="article"], [role="feed"], các chuỗi aria-label, và a.hfpxzc[href] là những phần lâu bền nhất; tên lớp thường thay đổi. Mô hình khám phá → trích xuất của kỹ năng này xử lý vấn đề này mà không cần thay đổi mã.

Q6: Tại sao phiên của tôi đôi khi trả về Access Denied hoặc trang CAPTCHA?
Một phân bổ proxy mới đôi khi rơi vào một địa chỉ IP bị đánh dấu. Yêu cầu đại lý gọi browser_close rồi browser_create lại để tạo một phiên mới. Các phân bổ tiếp theo sẽ thành công.

Q9: Có thể có nhiều đại lý chia sẻ một máy chủ MCP không?
Mỗi client nhận thức MCP kết nối tới phiên bản máy chủ riêng của nó (trong chế độ stdio) hoặc tới điểm cuối HTTP được chia sẻ (trong chế độ có thể stream). Các phiên được cô lập bởi taskId được trả về từ browser_create, vì vậy nhiều đại lý gọi cùng một máy chủ MCP sẽ không chia sẻ cookie hoặc trạng thái cuộn. Đối với việc thu thập dữ liệu có nhiều fan-out, hãy tạo một phiên mỗi truy vấn thay vì tái sử dụng một phiên lâu bền.

Q10: Các client MCP nào hoạt động với điều này?
Bất kỳ client nào hỗ trợ MCP. Giao thức là hợp đồng - danh sách công cụ của máy chủ và hình thức gọi là giống hệt trên mọi client. Bước 2 bao gồm các đường dẫn thiết lập cho Claude Desktop, Claude Code, Cursor, OpenAI Codex CLI, Gemini CLI và VS Code + GitHub Copilot Chat; đoạn JSON mcpServers tương tự có thể được sử dụng trong các client Python hoặc Node tùy chỉnh được xây dựng với MCP TypeScript SDK, và điểm cuối HTTP có thể stream tại https://api.scrapeless.com/mcp hoạt động với bất kỳ client HTTP nào.

Q11: Máy chủ MCP có công cụ Google Maps riêng không?
Không - máy chủ cung cấp các chức năng trình duyệt chung (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) cộng với các trợ giúp cấp trang (scrape_html, scrape_markdown, scrape_screenshot) và các công cụ dữ liệu Google (google_search, google_trends). Đại lý biên soạn việc thu thập dữ liệu từ các chức năng trình duyệt; các chức năng tương tự điều khiển Amazon, Home Depot, Etsy và bất kỳ trang web nào có JavaScript nặng.

Q12: Tại sao Maps tải lên trang đồng ý thay vì kết quả tìm kiếm?
Khi phiên trình duyệt đám mây đi qua một proxy dân cư châu Âu, Google can thiệp vào việc điều hướng bằng một trang chuyển tiếp consent.google.com trước khi hiển thị Maps. Đại lý nên gọi browser_get_text sau browser_goto và, nếu phản hồi chứa "consent" hoặc nhãn nút Chấp nhận (Accept all / Accetta tutto / Akzeptieren / Accepter), hãy gọi browser_click vào nút trước khi thử lại việc điều hướng. Bước 2 bao gồm đoạn mã đầy đủ.

Q13: Tại sao phiên của tôi đôi khi trả về lỗi kết nối tạm thời như os error 10054 hoặc 503?
Bể proxy dân cư Scrapeless đôi khi trả về lỗi cấp phát ngắn hạn trên browser_create. Một lần thử lại thường thành công - bọc browser_create trong vòng lặp thử lại 2–3 lần trong mã sản xuất, hoặc đơn giản là yêu cầu đại lý thử lại một lần.

Q14: Tôi có thể chạy bao nhiêu công việc thu thập dữ liệu MCP đồng thời?
Để đảm bảo độ tin cậy, giữ một client MCP cho một phiên đang diễn ra tại một thời điểm và xâu chuỗi các cuộc gọi trong một lượt của đại lý. Để có khả năng mở rộng cao hơn, chạy nhiều client MCP (hoặc tiến trình làm việc kết nối đến điểm cuối HTTP có thể stream) và giới hạn độ đồng thời ở ≤ 3 phiên mỗi máy chủ. Đối với các công việc hàng loạt thuần túy (10K+ truy vấn/giờ), điều khiển scrapeless-scraping-browser CLI trực tiếp với một nhóm làm việc song song; lộ trình MCP là tốt nhất cho việc khám phá do đại lý điều khiển và phủ địa lý kiểu ô.

Q15: Tôi có thể chạy điều này mà không có client MCP không?
Có. Hai con đường: (1) gọi điểm cuối HTTP có thể stream tại https://api.scrapeless.com/mcp trực tiếp từ bất kỳ client HTTP nào với tiêu đề x-api-token; (2) điều khiển trình duyệt đám mây thông qua scrapeless-scraping-browser CLI qua bash. Quy trình làm việc dựa trên MCP là con đường được khuyến nghị cho việc thu thập dữ liệu do đại lý thúc đẩy; CLI là con đường đúng cho các pipeline hàng loạt kịch bản.

Q16: Tại sao sử dụng URL /maps/search/<query> chuẩn thay vì điều khiển ô tìm kiếm?
URL tìm kiếm liên kết sâu đưa đại lý thẳng đến SERP đã được lấp đầy mà không cần phải nhấp vào ô tìm kiếm, gõ, và nhấn Enter. Ít cuộc gọi công cụ hơn, ít khả năng đại lý nhấp nhầm vào điều khiển sai, chạy nhanh hơn từ đầu đến cuối. Cách tiếp cận tương tự đối với URL địa điểm: điều hướng trực tiếp đến /maps/place/<slug>/data=!1s<placeId> thay vì điều khiển tìm kiếm rồi nhấp khi placeId đã được biết trước.

Tại Scrapless, chúng tôi chỉ truy cập dữ liệu có sẵn công khai trong khi tuân thủ nghiêm ngặt các luật, quy định và chính sách bảo mật trang web hiện hành. Nội dung trong blog này chỉ nhằm mục đích trình diễn và không liên quan đến bất kỳ hoạt động bất hợp pháp hoặc vi phạm nào. Chúng tôi không đảm bảo và từ chối mọi trách nhiệm đối với việc sử dụng thông tin từ blog này hoặc các liên kết của bên thứ ba. Trước khi tham gia vào bất kỳ hoạt động cạo nào, hãy tham khảo ý kiến ​​cố vấn pháp lý của bạn và xem xét các điều khoản dịch vụ của trang web mục tiêu hoặc có được các quyền cần thiết.

Bài viết phổ biến nhất

Danh mục