Skip to content

Examples

Practical examples and common use cases for the Google Search Console library.

Basic Examples

Top Performing Queries

Get your top 10 performing queries for the last 30 days:

import searchconsole

account = searchconsole.authenticate(
    client_config='client_secrets.json',
    credentials='credentials.json'
)

webproperty = account['https://www.example.com/']

# Query top queries
report = (
    webproperty.query
    .range('today', days=-30)
    .dimension('query')
    .limit(10)
    .get()
)

print("Top 10 Queries (Last 30 Days)\n" + "="*50)
for i, row in enumerate(report, 1):
    print(f"{i:2d}. {row.query}")
    print(f"    Clicks: {row.clicks:>6,} | Impressions: {row.impressions:>8,}")
    print(f"    CTR: {row.ctr:>6.2%} | Avg Position: {row.position:>5.1f}\n")

Top Pages by Traffic

Find which pages are driving the most traffic:

report = (
    webproperty.query
    .range('today', days=-30)
    .dimension('page')
    .limit(20)
    .get()
)

# Convert to DataFrame for easier analysis
df = report.to_dataframe()

# Sort by clicks
top_pages = df.nlargest(10, 'clicks')

print("Top 10 Pages by Clicks\n")
for idx, row in top_pages.iterrows():
    print(f"{row['page']}")
    print(f"  {row['clicks']:,} clicks, {row['impressions']:,} impressions\n")

Track Specific Keywords

Monitor performance of specific keywords over time:

keywords = ['python tutorial', 'learn python', 'python for beginners']

for keyword in keywords:
    report = (
        webproperty.query
        .range('today', days=-90)
        .dimension('date')
        .filter('query', keyword, 'equals')
        .get()
    )

    df = report.to_dataframe()

    print(f"\n{keyword.upper()}")
    print(f"Total clicks: {df['clicks'].sum():,}")
    print(f"Total impressions: {df['impressions'].sum():,}")
    print(f"Average position: {df['position'].mean():.1f}")

Analysis Examples

Click-Through Rate Analysis

Analyze CTR by position range:

import pandas as pd

# Get query-level data
report = (
    webproperty.query
    .range('today', days=-30)
    .dimension('query')
    .get()
)

df = report.to_dataframe()

# Categorize by position
df['position_range'] = pd.cut(
    df['position'],
    bins=[0, 3, 5, 10, 20, 100],
    labels=['1-3', '4-5', '6-10', '11-20', '20+']
)

# Analyze by position range
analysis = df.groupby('position_range').agg({
    'clicks': 'sum',
    'impressions': 'sum',
    'ctr': 'mean',
    'position': 'mean'
}).round(4)

print(analysis)

Geographic Performance

Compare performance across countries:

report = (
    webproperty.query
    .range('today', days=-30)
    .dimension('country')
    .get()
)

df = report.to_dataframe()

# Sort by clicks
df = df.sort_values('clicks', ascending=False)

print("Performance by Country\n")
print(df.head(10).to_string(index=False))

# Calculate percentage of total
df['click_share'] = (df['clicks'] / df['clicks'].sum() * 100).round(2)

top_5 = df.head(5)
print(f"\nTop 5 Countries Account for {top_5['click_share'].sum():.1f}% of Clicks")

Device Breakdown

Analyze traffic by device type:

report = (
    webproperty.query
    .range('today', days=-30)
    .dimension('device')
    .get()
)

df = report.to_dataframe()

print("Performance by Device\n")
for _, row in df.iterrows():
    print(f"{row['device'].upper()}")
    print(f"  Clicks: {row['clicks']:,}")
    print(f"  Impressions: {row['impressions']:,}")
    print(f"  CTR: {row['ctr']:.2%}")
    print(f"  Avg Position: {row['position']:.1f}\n")

# Calculate device share
df['device_share'] = (df['clicks'] / df['clicks'].sum() * 100)

print("Click Share by Device:")
for _, row in df.iterrows():
    print(f"  {row['device']}: {row['device_share']:.1f}%")

Trend Analysis

Track performance trends over time:

import matplotlib.pyplot as plt

# Get daily data for the last 90 days
report = (
    webproperty.query
    .range('today', days=-90)
    .dimension('date')
    .get()
)

df = report.to_dataframe()
df['date'] = pd.to_datetime(df['date'])
df = df.sort_values('date')

# Plot trends
fig, axes = plt.subplots(2, 2, figsize=(15, 10))

# Clicks trend
axes[0, 0].plot(df['date'], df['clicks'], marker='o')
axes[0, 0].set_title('Clicks Over Time')
axes[0, 0].set_xlabel('Date')
axes[0, 0].set_ylabel('Clicks')

# Impressions trend
axes[0, 1].plot(df['date'], df['impressions'], marker='o', color='orange')
axes[0, 1].set_title('Impressions Over Time')
axes[0, 1].set_xlabel('Date')
axes[0, 1].set_ylabel('Impressions')

# CTR trend
axes[1, 0].plot(df['date'], df['ctr'] * 100, marker='o', color='green')
axes[1, 0].set_title('CTR Over Time')
axes[1, 0].set_xlabel('Date')
axes[1, 0].set_ylabel('CTR (%)')

# Position trend
axes[1, 1].plot(df['date'], df['position'], marker='o', color='red')
axes[1, 1].set_title('Average Position Over Time')
axes[1, 1].set_xlabel('Date')
axes[1, 1].set_ylabel('Position')
axes[1, 1].invert_yaxis()  # Lower position is better

plt.tight_layout()
plt.savefig('search_console_trends.png')
print("Trend chart saved to search_console_trends.png")

Content Analysis Examples

Blog Post Performance

Analyze all blog posts:

# Get all pages containing '/blog/'
report = (
    webproperty.query
    .range('today', days=-30)
    .dimension('page')
    .filter('page', '/blog/', 'contains')
    .get()
)

df = report.to_dataframe()

print(f"Total blog posts: {len(df)}")
print(f"Total blog clicks: {df['clicks'].sum():,}")
print(f"Total blog impressions: {df['impressions'].sum():,}")

# Top performing blog posts
top_blogs = df.nlargest(10, 'clicks')

print("\nTop 10 Blog Posts:\n")
for idx, row in top_blogs.iterrows():
    # Extract title from URL (customize as needed)
    title = row['page'].split('/')[-2].replace('-', ' ').title()
    print(f"{title}")
    print(f"  URL: {row['page']}")
    print(f"  Clicks: {row['clicks']:,} | Impressions: {row['impressions']:,}")
    print(f"  CTR: {row['ctr']:.2%} | Position: {row['position']:.1f}\n")

Find Underperforming Pages

Identify pages with high impressions but low clicks:

report = (
    webproperty.query
    .range('today', days=-30)
    .dimension('page')
    .get()
)

df = report.to_dataframe()

# Filter for pages with significant impressions
significant_pages = df[df['impressions'] >= 100].copy()

# Sort by CTR (ascending) to find underperformers
underperformers = significant_pages.nsmallest(10, 'ctr')

print("Top 10 Underperforming Pages (High Impressions, Low CTR)\n")
for idx, row in underperformers.iterrows():
    print(f"{row['page']}")
    print(f"  Impressions: {row['impressions']:,} | Clicks: {row['clicks']}")
    print(f"  CTR: {row['ctr']:.2%} | Position: {row['position']:.1f}")
    print(f"  💡 Opportunity: Improve meta description or title tag\n")

Content Gap Analysis

Find queries where you rank but have low clicks:

# Get queries with position in top 10 but low CTR
report = (
    webproperty.query
    .range('today', days=-30)
    .dimension('query')
    .get()
)

df = report.to_dataframe()

# Filter for top 10 positions with at least 50 impressions
top_10 = df[(df['position'] <= 10) & (df['impressions'] >= 50)].copy()

# Sort by CTR to find opportunities
opportunities = top_10.nsmallest(20, 'ctr')

print("Ranking Opportunities (Top 10 Position, Low CTR)\n")
for idx, row in opportunities.iterrows():
    print(f"Query: {row['query']}")
    print(f"  Position: {row['position']:.1f} | CTR: {row['ctr']:.2%}")
    print(f"  Clicks: {row['clicks']} | Impressions: {row['impressions']}")
    print(f"  💡 Consider: Optimizing for featured snippets or improving title\n")

Comparison Examples

Month-over-Month Comparison

Compare current month to previous month:

import datetime

# Current month data
this_month_start = datetime.date.today().replace(day=1)
this_month_report = (
    webproperty.query
    .range(this_month_start, 'today')
    .dimension('query')
    .get()
)

# Previous month data
last_month_end = this_month_start - datetime.timedelta(days=1)
last_month_start = last_month_end.replace(day=1)
last_month_report = (
    webproperty.query
    .range(last_month_start, last_month_end)
    .dimension('query')
    .get()
)

# Convert to DataFrames
this_month_df = this_month_report.to_dataframe()
last_month_df = last_month_report.to_dataframe()

# Compare totals
this_month_clicks = this_month_df['clicks'].sum()
last_month_clicks = last_month_df['clicks'].sum()
change = ((this_month_clicks - last_month_clicks) / last_month_clicks * 100)

print(f"Month-over-Month Performance\n{'='*50}")
print(f"\nThis Month:")
print(f"  Clicks: {this_month_clicks:,}")
print(f"  Impressions: {this_month_df['impressions'].sum():,}")

print(f"\nLast Month:")
print(f"  Clicks: {last_month_clicks:,}")
print(f"  Impressions: {last_month_df['impressions'].sum():,}")

print(f"\nChange: {change:+.1f}%")

Year-over-Year Comparison

Compare to the same period last year:

import datetime

# This year (last 30 days)
this_year_report = (
    webproperty.query
    .range('today', days=-30)
    .dimension('date')
    .get()
)

# Last year (same 30-day period)
days_ago_365 = datetime.date.today() - datetime.timedelta(days=365)
days_ago_395 = days_ago_365 - datetime.timedelta(days=30)

last_year_report = (
    webproperty.query
    .range(days_ago_395, days_ago_365)
    .dimension('date')
    .get()
)

# Compare
this_year_df = this_year_report.to_dataframe()
last_year_df = last_year_report.to_dataframe()

metrics = {
    'Clicks': ('clicks', this_year_df['clicks'].sum(), last_year_df['clicks'].sum()),
    'Impressions': ('impressions', this_year_df['impressions'].sum(), last_year_df['impressions'].sum()),
    'CTR': ('ctr', this_year_df['ctr'].mean(), last_year_df['ctr'].mean()),
    'Position': ('position', this_year_df['position'].mean(), last_year_df['position'].mean()),
}

print("Year-over-Year Comparison (Last 30 Days)\n")
for metric_name, (col, this_year, last_year) in metrics.items():
    change = ((this_year - last_year) / last_year * 100) if last_year > 0 else 0
    print(f"{metric_name}:")
    print(f"  This Year: {this_year:,.2f}")
    print(f"  Last Year: {last_year:,.2f}")
    print(f"  Change: {change:+.1f}%\n")

Search Type Examples

Image Search Analysis

Analyze image search performance:

# Get image search data
image_report = (
    webproperty.query
    .search_type('image')
    .range('today', days=-30)
    .dimension('page')
    .get()
)

df = image_report.to_dataframe()

print("Image Search Performance\n")
print(f"Total clicks: {df['clicks'].sum():,}")
print(f"Total impressions: {df['impressions'].sum():,}")
print(f"Average CTR: {df['ctr'].mean():.2%}")

# Top performing image pages
top_images = df.nlargest(10, 'clicks')
print("\nTop 10 Pages for Image Search:\n")
for idx, row in top_images.iterrows():
    print(f"{row['page']}")
    print(f"  Clicks: {row['clicks']:,} | Impressions: {row['impressions']:,}\n")

Compare Search Types

Compare performance across different search types:

search_types = ['web', 'image', 'video', 'news']

results = []
for search_type in search_types:
    try:
        report = (
            webproperty.query
            .search_type(search_type)
            .range('today', days=-30)
            .dimension('page')
            .get()
        )

        df = report.to_dataframe()

        results.append({
            'search_type': search_type,
            'clicks': df['clicks'].sum(),
            'impressions': df['impressions'].sum(),
            'ctr': df['ctr'].mean()
        })
    except Exception as e:
        print(f"No data for {search_type}: {e}")

# Display comparison
import pandas as pd
comparison_df = pd.DataFrame(results)

print("Search Type Comparison\n")
print(comparison_df.to_string(index=False))

# Visualize
comparison_df.plot(
    x='search_type',
    y=['clicks', 'impressions'],
    kind='bar',
    title='Clicks and Impressions by Search Type'
)

Google Discover Performance

Analyze Google Discover traffic:

# Note: Discover doesn't return position data
discover_report = (
    webproperty.query
    .search_type('discover')
    .range('today', days=-30)
    .dimension('page')
    .get()
)

df = discover_report.to_dataframe()

print("Google Discover Performance (Last 30 Days)\n")
print(f"Total clicks: {df['clicks'].sum():,}")
print(f"Total impressions: {df['impressions'].sum():,}")
print(f"Average CTR: {df['ctr'].mean():.2%}")

# Top Discover pages
top_discover = df.nlargest(10, 'clicks')
print("\nTop 10 Pages in Discover:\n")
for idx, row in top_discover.iterrows():
    print(f"{row['page']}")
    print(f"  Clicks: {row['clicks']:,} | CTR: {row['ctr']:.2%}\n")

Advanced Filtering Examples

Multi-Filter Analysis

Analyze mobile traffic from USA for blog posts:

report = (
    webproperty.query
    .range('today', days=-30)
    .dimension('query', 'page')
    .filter('page', '/blog/', 'contains')
    .filter('country', 'usa', 'equals')
    .filter('device', 'mobile', 'equals')
    .get()
)

df = report.to_dataframe()

print("Mobile Traffic (USA) for Blog Posts\n")
print(f"Total clicks: {df['clicks'].sum():,}")
print(f"Unique queries: {df['query'].nunique()}")
print(f"Unique pages: {df['page'].nunique()}")

# Top queries for this segment
top_queries = df.groupby('query').agg({
    'clicks': 'sum',
    'impressions': 'sum'
}).nlargest(10, 'clicks')

print("\nTop 10 Mobile Queries (USA, Blog):\n")
print(top_queries)

Regex Filtering

Find all date-based URLs:

# Find URLs matching pattern /blog/YYYY/MM/
report = (
    webproperty.query
    .range('today', days=-30)
    .dimension('page')
    .filter('page', r'/blog/\d{4}/\d{2}/', 'includingRegex')
    .get()
)

df = report.to_dataframe()

print(f"Found {len(df)} blog posts with date-based URLs\n")

# Extract year and month
import re

def extract_date(url):
    match = re.search(r'/blog/(\d{4})/(\d{2})/', url)
    if match:
        return f"{match.group(1)}-{match.group(2)}"
    return None

df['year_month'] = df['page'].apply(extract_date)

# Analyze by year-month
monthly_performance = df.groupby('year_month').agg({
    'clicks': 'sum',
    'impressions': 'sum',
    'page': 'count'
}).rename(columns={'page': 'num_posts'})

print("Performance by Publication Month:\n")
print(monthly_performance.sort_index(ascending=False))

Exclude Internal Pages

Filter out admin and internal pages:

# Get all pages except admin, staging, or test pages
report = (
    webproperty.query
    .range('today', days=-30)
    .dimension('page')
    .filter('page', '/admin/', 'notContains')
    .filter('page', 'staging.', 'notContains')
    .filter('page', '/test/', 'notContains')
    .get()
)

df = report.to_dataframe()

print(f"Public pages: {len(df)}")
print(f"Total clicks: {df['clicks'].sum():,}")

Next Steps