如何從 Google 地圖中提取商家名稱、評分和評論

了解如何使用 Python 和 TalorData SERP API 從類似 Google 地圖的搜尋結果中提取商家名稱、評分、評論數量、類別、地址、電話號碼、網站及地點 ID。

如何從 Google 地圖中提取商家名稱、評分和評論
Lila Montclair
最後更新於
6 分鐘閱讀

Google Maps 是分析本地商家可見度的重要資料來源。如果你想研究餐廳、牙醫診所、飯店、健身房、水電工、代理商或其他本地商家類別,通常最先需要的是幾個基礎欄位:

欄位

用途

Business name

識別商家

Rating

判斷口碑品質

Review count

判斷評論量和信任度

Category

商家分類

Address

匹配地區市場

Phone number

用於 lead workflows

Website

用於資料補全

Position

判斷 local search visibility

Place ID / data CID

用於去重和追蹤

真正麻煩的不是理解這些欄位,而是穩定地收集它們。

如果用 browser automation 手動抓 Google Maps,頁面結構、動態載入、結果滾動、不同地點返回不同結果,都會讓流程變脆。SERP API workflow 的價值,就是把 Google Maps-style results 變成更容易解析、保存和比較的 structured JSON。TalorData SERP API 支援 structured JSON / HTML output、geo-targeted SERP data,也覆蓋 Maps 和 Local 這類 Google result types。

這篇會示範如何用 Python 和 TalorData 提取 Google Maps 中的 business names、ratings 和 review counts。

我們要做什麼?

這篇會建立一個 Python script,用來:

  1. 發送 Google Maps search query

  2. 從 TalorData 取得 structured JSON

  3. 提取 business names、ratings、review counts、categories、addresses、websites 和 phone numbers

  4. 標準化資料

  5. 匯出 CSV

流程如下:

Search query + location
   ↓
TalorData SERP API
   ↓
Google Maps results in JSON
   ↓
Extract business fields
   ↓
Save CSV or database

可以提取哪些資料?

本地商家資料通常先從這些欄位開始:

Field

Example

title or name

Example Coffee

rating

4.6

reviews or review_count

1280

category or type

Coffee shop

address

123 Example St, New York

phone

+1 212-000-0000

website

https://example.com

place_id

ChIJExample

data_cid

123456789

position

1

latitude

40.7455

longitude

-74.0083

maps_url

Google Maps listing URL

在 Maps workflow 裡,business name、place ID、address、coordinates、category、rating、review count、rank position、opening status、phone number、website、Google Maps URL、thumbnail 和 price level 都是常見可用欄位。

Step 1:準備 API key

將 TalorData API key 和 endpoint 存成環境變數。

export TALORDATA_API_KEY="your_api_key_here"
export TALORDATA_SERP_ENDPOINT="your_talordata_serp_endpoint_here"

Windows PowerShell:

setx TALORDATA_API_KEY "your_api_key_here"
setx TALORDATA_SERP_ENDPOINT "your_talordata_serp_endpoint_here"

安裝 Python dependencies:

pip install requests pandas

Step 2:發送 Google Maps request

Request 需要 query 和 location context。對 local search 來說,座標通常比城市名稱更精準,因為 Google Maps results 可能街區之間就有差異。

import os
import requests
from typing import Any, Dict, Optional


TALORDATA_API_KEY = os.getenv("TALORDATA_API_KEY")
TALORDATA_SERP_ENDPOINT = os.getenv("TALORDATA_SERP_ENDPOINT")


def fetch_google_maps(
    query: str,
    ll: str,
    hl: str = "en",
    gl: str = "us",
    google_domain: str = "google.com",
    no_cache: bool = True,
    extra_params: Optional[Dict[str, Any]] = None
) -> Dict[str, Any]:
    """
    Fetch Google Maps-style search results with TalorData SERP API.

    ll format example:
    @40.7455096,-74.0083012,14z
    """
    if not TALORDATA_API_KEY:
        raise RuntimeError("Missing TALORDATA_API_KEY environment variable.")

    if not TALORDATA_SERP_ENDPOINT:
        raise RuntimeError("Missing TALORDATA_SERP_ENDPOINT environment variable.")

    payload: Dict[str, Any] = {
        "engine": "google_maps",
        "type": "search",
        "q": query,
        "ll": ll,
        "hl": hl,
        "gl": gl,
        "google_domain": google_domain,
        "no_cache": no_cache
    }

    if extra_params:
        payload.update(extra_params)

    response = requests.post(
        TALORDATA_SERP_ENDPOINT,
        json=payload,
        headers={
            "Authorization": f"Bearer {TALORDATA_API_KEY}",
            "Content-Type": "application/json"
        },
        timeout=30
    )

    response.raise_for_status()
    return response.json()

基本執行:

if __name__ == "__main__":
    data = fetch_google_maps(
        query="coffee shops",
        ll="@40.7455096,-74.0083012,14z",
        hl="en",
        gl="us"
    )

    print(data)

Step 3:檢查 raw response

寫 parser 前,先看 JSON structure。

import json

print(json.dumps(data, indent=2, ensure_ascii=False)[:5000])

結果可能放在這類欄位中:

local_results
maps_results
place_results
results
organic_results

不同 result type 可能有不同容器。Parser 不要一開始就做成石碑,留一點彈性。

Step 4:解析商家名稱、評分和評論數

下面的 parser 會檢查多個可能的 result containers,並提取常見商家欄位。

from typing import Any, Dict, List


def get_first_available_list(data: Dict[str, Any], keys: List[str]) -> List[Dict[str, Any]]:
    for key in keys:
        value = data.get(key)

        if isinstance(value, list):
            return value

    return []


def parse_business_results(data: Dict[str, Any]) -> List[Dict[str, Any]]:
    items = get_first_available_list(
        data,
        keys=[
            "local_results",
            "maps_results",
            "place_results",
            "results",
            "organic_results"
        ]
    )

    rows = []

    for index, item in enumerate(items, start=1):
        gps = item.get("gps_coordinates") or {}
        links = item.get("links") or {}

        rows.append({
            "position": item.get("position", index),
            "business_name": item.get("title") or item.get("name"),
            "rating": item.get("rating"),
            "review_count": item.get("reviews") or item.get("review_count"),
            "category": item.get("type") or item.get("category"),
            "address": item.get("address"),
            "phone": item.get("phone"),
            "website": item.get("website") or links.get("website"),
            "place_id": item.get("place_id"),
            "data_cid": item.get("data_cid") or item.get("cid"),
            "maps_url": item.get("link") or item.get("maps_url"),
            "latitude": gps.get("latitude") or item.get("latitude"),
            "longitude": gps.get("longitude") or item.get("longitude"),
            "open_state": item.get("open_state") or item.get("hours"),
            "price_level": item.get("price") or item.get("price_level")
        })

    return rows

使用方式:

data = fetch_google_maps(
    query="coffee shops",
    ll="@40.7455096,-74.0083012,14z"
)

businesses = parse_business_results(data)

for business in businesses[:5]:
    print(
        business["position"],
        business["business_name"],
        business["rating"],
        business["review_count"]
    )

Step 5:匯出 CSV

CSV 適合快速檢查、人工 QA、Excel 分析、CRM 匯入或 BI dashboard。

import pandas as pd


data = fetch_google_maps(
    query="coffee shops",
    ll="@40.7455096,-74.0083012,14z"
)

businesses = parse_business_results(data)

df = pd.DataFrame(businesses)
df.to_csv("google_maps_businesses.csv", index=False)

print(df.head())

範例表格:

position

business_name

rating

review_count

category

1

Example Coffee

4.6

1280

Coffee shop

2

Sample Cafe

4.4

760

Cafe

3

Local Roasters

4.7

420

Coffee roasters

Step 6:清理 rating 和 review count

Rating 和 review count 可能是 string,也可能是 number。分析前先轉成數字。

df["rating_num"] = pd.to_numeric(df["rating"], errors="coerce")
df["review_count_num"] = pd.to_numeric(df["review_count"], errors="coerce")

按口碑強度排序:

top_reputation = df.sort_values(
    by=["rating_num", "review_count_num"],
    ascending=[False, False]
)

top_reputation.to_csv("top_rated_businesses.csv", index=False)

print(top_reputation[[
    "business_name",
    "rating",
    "review_count",
    "category",
    "address"
]].head(10))

Rating 和 review count 要一起看。

Case

Meaning

High rating + high review count

口碑強

High rating + low review count

分數高,但樣本少

Low rating + high review count

知名度高,但有口碑風險

No rating

可能是新 listing 或資料不完整

High position + weak reviews

可見度強,但信任感弱

4.9 分但只有 12 則評論,和 4.6 分但有 2,000 則評論,不是同一件事。

Step 7:加入 search context

如果要比較不同時間的結果,每一列都要保存 search context。

from datetime import datetime, timezone


def add_search_context(
    rows: List[Dict[str, Any]],
    query: str,
    ll: str,
    hl: str,
    gl: str
) -> List[Dict[str, Any]]:
    collected_at = datetime.now(timezone.utc).isoformat()

    for row in rows:
        row["query"] = query
        row["ll"] = ll
        row["hl"] = hl
        row["gl"] = gl
        row["collected_at"] = collected_at

    return rows

使用:

query = "coffee shops"
ll = "@40.7455096,-74.0083012,14z"
hl = "en"
gl = "us"

data = fetch_google_maps(query=query, ll=ll, hl=hl, gl=gl)
rows = parse_business_results(data)
rows = add_search_context(rows, query=query, ll=ll, hl=hl, gl=gl)

pd.DataFrame(rows).to_csv("google_maps_snapshot.csv", index=False)

這樣就能追蹤:

Change

Meaning

Position changed

本地排名變化

Rating changed

口碑變化

Review count increased

顧客回饋增加

Business disappeared

可見度變化

New competitor appeared

市場變化

Website or phone appeared

Listing completeness 改善

Step 8:去重商家

Business names 可能變化,地址格式也可能不同。去重時優先使用穩定 ID。

建議順序:

  1. place_id

  2. data_cid

  3. Business name + address

  4. Business name + latitude + longitude

def build_business_key(row: Dict[str, Any]) -> str:
    if row.get("place_id"):
        return f"place_id:{row['place_id']}"

    if row.get("data_cid"):
        return f"data_cid:{row['data_cid']}"

    name = str(row.get("business_name") or "").lower().strip()
    address = str(row.get("address") or "").lower().strip()

    return f"name_address:{name}|{address}"


df["business_key"] = df.apply(lambda row: build_business_key(row.to_dict()), axis=1)
df = df.drop_duplicates(subset=["business_key"])

當你跨多個座標收集同一類商家時,這一步尤其重要。

Step 9:跨多個地點搜尋

Local SEO 只查一個座標通常不夠。可以建立 coordinate grid。

locations = [
    {
        "label": "Manhattan West",
        "ll": "@40.7455096,-74.0083012,14z"
    },
    {
        "label": "Times Square",
        "ll": "@40.758896,-73.985130,14z"
    },
    {
        "label": "Lower Manhattan",
        "ll": "@40.707491,-74.011276,14z"
    }
]

all_rows = []

for location in locations:
    data = fetch_google_maps(
        query="coffee shops",
        ll=location["ll"],
        hl="en",
        gl="us"
    )

    rows = parse_business_results(data)

    for row in rows:
        row["grid_location"] = location["label"]

    rows = add_search_context(
        rows,
        query="coffee shops",
        ll=location["ll"],
        hl="en",
        gl="us"
    )

    all_rows.extend(rows)

pd.DataFrame(all_rows).to_csv("google_maps_multi_location.csv", index=False)

這能回答:

Question

What to measure

哪些商家出現最頻繁?

Presence across locations

哪個商家平均排名最好?

Local visibility

哪些競品評論更強?

Rating + review count

哪些區域競爭更激烈?

Strong listings 數量

哪些地點覆蓋較弱?

Missing 或 low-quality results

常見錯誤

只提取 business name

Business name 本身不夠。應盡量一起提取 rating、review count、category、address、phone、website 和 place ID。

忽略 location

Google Maps results 是本地結果。要保存 coordinate、zoom level、language 和 country context。

把 rating 當成全部口碑

Rating 必須搭配 review count。高分但評論少,信號可能不穩。

不做去重

同一商家可能出現在多個搜尋中。優先使用 place_iddata_cid 去重。

覆蓋歷史快照

如果要做 monitoring,應 append 新資料,而不是替換舊檔案。

不保存 raw JSON

開發階段要保存 raw response。Parser 出問題時會好修很多。

結語

從 Google Maps 提取 business names、ratings 和 reviews,適合 local SEO、lead generation、competitor research、market analysis、review monitoring 和 AI agents。

乾淨流程是:

  1. 發送 local Maps query

  2. 取得 structured JSON

  3. 提取 business name、rating、review count、category、address、website、phone 和 place ID

  4. 保存 search context

  5. 匯出 CSV 或寫入 database

  6. 持續追蹤變化

Google Maps 像一條擁擠街道。結構化資料會把它變成有路燈的表格。開始免費試用Google Maps API>>

立即開展您的數據業務

加入全球最強大的代理網絡

免費試用