Local SEO & Google Business ProfileLocal rank tracking, reporting and audits · Lesson 16 of 17

Hands-on: local performance data with Search Console, GBP data, Python and Sheets

Article · 14 min · 8 min lecture

Video lecture

Hands-on: local performance data with Search Console, GBP data, Python and Sheets

13 chapters · about 8 min · full transcript

Coming soon

Chapter 1 of 13

Hands-on: local performance data

  • Search Console
  • Business Profile performance
  • GA4 via UTMs
  • One dashboard

The narrated lecture is in production

Every chapter is scripted and ready. Browse the chapters and read the full transcript now — the video will appear here when it’s published.

Chapters

What you are building

A simple monthly local dashboard that combines three sources:

  1. Search Console — organic clicks and impressions for location and service pages, and "local" queries (city names, "near me").
  2. Business Profile performance — calls, direction requests, website clicks and impressions from Search and Maps.
  3. GA4 — sessions and conversions from the UTM-tagged profile link.

You can do all of it by exporting CSVs into Google Sheets. Python makes it repeatable for multi-location businesses.

Part 1: Search Console in Sheets (no code)

In Search Console → Performance → Search results, filter Page by "URLs containing" /locations/ (or your pattern) and export. For local queries, use Query → "Custom (regex)" with a pattern such as:

near me|nearby|lahore|gulberg|dha|karachi|clifton

Search Console filters use RE2 regular expression syntax. Export both views monthly into tabs GSC_pages and GSC_queries, then summarise with a pivot table or:

=QUERY(GSC_pages!A:E, "select A, sum(B), sum(C) where A contains '/locations/' group by A order by sum(B) desc", 1)

Part 2: Search Console API in Python (repeatable)

Create a Google Cloud service account, enable the Search Console API, and add the service account email as a user on the property. Keep the key file path in an environment variable.

import os
import pandas as pd
from google.oauth2 import service_account
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

SITE = os.environ.get("GSC_SITE", "sc-domain:example.com")
creds = service_account.Credentials.from_service_account_file(
    os.environ["GSC_SERVICE_ACCOUNT_JSON"],
    scopes=["https://www.googleapis.com/auth/webmasters.readonly"])
gsc = build("searchconsole", "v1", credentials=creds)

def query(body: dict) -> pd.DataFrame:
    try:
        resp = gsc.searchanalytics().query(siteUrl=SITE, body=body).execute()
    except HttpError as e:
        raise SystemExit(f"Search Console API error: {e}")
    rows = resp.get("rows", [])
    dims = body["dimensions"]
    return pd.DataFrame([{**dict(zip(dims, r["keys"])), "clicks": r["clicks"],
                          "impressions": r["impressions"], "position": r["position"]} for r in rows])

location_pages = query({
    "startDate": "2026-08-01", "endDate": "2026-08-31",
    "dimensions": ["page"],
    "dimensionFilterGroups": [{"filters": [
        {"dimension": "page", "operator": "contains", "expression": "/locations/"}]}],
    "rowLimit": 25000,
})
local_queries = query({
    "startDate": "2026-08-01", "endDate": "2026-08-31",
    "dimensions": ["query", "page"],
    "dimensionFilterGroups": [{"filters": [
        {"dimension": "query", "operator": "includingRegex", "expression": "near me|lahore|karachi"}]}],
    "rowLimit": 25000,
})
location_pages.to_csv("gsc_location_pages_2026-08.csv", index=False)
local_queries.to_csv("gsc_local_queries_2026-08.csv", index=False)
print(location_pages.sort_values("clicks", ascending=False).head(10))

Note: Search Console anonymises some rare queries, so query-level totals are lower than page-level totals. Compare like with like.

Part 3: Business Profile performance data

Without code: in the Business Profile, open Performance, choose the date range and export or record the monthly figures (calls, directions, website clicks, bookings, views on Search/Maps). For many locations, the Business Profile manager supports multi-location performance downloads.

With the API (approved developers): Google's Business Profile Performance API returns daily metrics per location. Access requires applying for Business Profile API access, OAuth consent by an account that manages the location, and the https://www.googleapis.com/auth/business.manage scope. A minimal request using an authorised session:

from google.auth.transport.requests import AuthorizedSession
from google_auth_oauthlib.flow import InstalledAppFlow

flow = InstalledAppFlow.from_client_secrets_file(
    "client_secret.json", scopes=["https://www.googleapis.com/auth/business.manage"])
creds = flow.run_local_server(port=0)          # the location's owner/manager signs in
session = AuthorizedSession(creds)

LOCATION_ID = "1234567890"                      # from the Business Profile / API
url = (f"https://businessprofileperformance.googleapis.com/v1/locations/{LOCATION_ID}"
       ":fetchMultiDailyMetricsTimeSeries")
params = [("dailyMetrics", m) for m in ("CALL_CLICKS", "WEBSITE_CLICKS", "BUSINESS_DIRECTION_REQUESTS")]
params += [("dailyRange.startDate.year", 2026), ("dailyRange.startDate.month", 8), ("dailyRange.startDate.day", 1),
           ("dailyRange.endDate.year", 2026), ("dailyRange.endDate.month", 8), ("dailyRange.endDate.day", 31)]
resp = session.get(url, params=params, timeout=30)
resp.raise_for_status()
print(resp.json())                               # nested time series per metric

Metric names and response shapes can change — check the current Business Profile Performance API reference before relying on this in production, and store OAuth tokens securely.

Part 4: GA4

In GA4, build an exploration with Session campaign = gbp-listing (from your UTM convention) and dimensions Landing page and Session source/medium, metrics Sessions, Key events (conversions). Export monthly into a GA4_gbp tab.

Part 5: The monthly dashboard tab

Location | GSC clicks (location page) | GSC impressions | Local-query clicks | GBP calls | GBP directions
GBP website clicks | GA4 gbp sessions | GA4 key events | Reviews (new) | Avg rating | Notes

Fill it with SUMIF/XLOOKUP from the source tabs, add month-on-month and year-on-year columns, and chart the three numbers the owner cares about most (usually calls, directions and conversions). If you use Looker Studio, connect it to the Sheet rather than rebuilding logic in two places.

Worked example (illustrative)

A 4-branch optician chain in Lahore and Karachi runs the Python script monthly and pastes GBP performance exports into the Sheet. The dashboard shows Gulberg's location page gaining impressions but its GBP calls flat, while Clifton's calls rise after a category fix. Investigation shows Gulberg's profile links to the home page rather than its location page, and the phone number on the page is the head office. Fixing both aligns the page, the profile and the calls — and the next month's dashboard shows it.

Common mistakes

  • Adding query-level and page-level Search Console totals together.
  • Hard-coding API keys or OAuth secrets in scripts.
  • Reporting impressions without the actions and conversions that follow.
  • Building the same logic separately in Sheets, Looker Studio and slides.

Key takeaways

  • Combine Search Console, Business Profile performance and GA4 (UTM-tagged) data for a complete local picture.
  • Sheets exports and regex filters are enough for one location; the Search Console API makes it repeatable at scale.
  • The Business Profile Performance API needs approved access, OAuth by a profile manager and the business.manage scope.
  • Keep secrets in environment variables, compare like with like, and chart the actions owners care about.

Check your understanding

Quick questions to lock in the lesson. They don’t count towards your certificate.

  1. Why are query-level Search Console totals often lower than page-level totals?
  2. Which OAuth scope does the Business Profile Performance API use?

Put it into practice

Build the monthly dashboard for one business: export location-page and local-query data from Search Console, record GBP performance and GA4 gbp-listing sessions, and write two observations with actions.

Enrol for free to save your progress

Reading is always free. Enrol to keep your place, take the final assessment and earn a verifiable certificate.