如何从 Google 地图提取商家名称、评分和评论

了解如何使用 Python 和 TalorData SERP API 从类似 Google 地图的搜索结果中提取商家名称、评分、评论数量、类别、地址、电话号码、网站及地点 ID。

talor ai
最後更新於
7 分鐘閱讀

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>>

立即開展您的數據業務

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

免費試用