Search Console - SEO - Python - creators - automation
6 min lectura

Find Blog Pages with High Impressions and Few Clicks from Search Console CSVs

Export two Search Console periods and run a tested Python script to shortlist blog pages with impressions but few clicks, then review before editing.

Find Blog Pages with High Impressions and Few Clicks from Search Console CSVs

Your blog has 200 articles and you plan to publish ten more this week. Before opening another URL, check whether an existing page is already shown hundreds of times in Google but earns few clicks. You can scan Search Console manually; two CSV exports and a small script turn that scan into a repeatable shortlist so your attention goes to the ten most visible candidates.

This builds on a SoyJB example about improving an existing URL before duplicating a topic. The task here is different: turn comparable exports from the Pages tab into a reproducible list. The script does not edit your site or automatically “fix SEO.”

1. Export two complete periods

In Search Console open Performance → Search results. Use the same search type and filters for both periods, then choose 28 complete days. Open Pages, select Export → CSV, and save the table as current.csv. Repeat for the preceding 28 days and save previous.csv. Avoid the current day or preliminary data; Google notes that very recent figures can change.

There is a practical limit: a standard Search Console export can contain only 1,000 representative table rows even when chart totals are larger. This script is a useful first pass for a smaller site, not proof that it covered every URL on a large publication. For more complete coverage, use the Search Console API or bulk export.

2. Run a small local script

Save the code below as gsc_csv_opportunities.py beside the two CSV files. It recognizes common English and Spanish headers, keeps blog URLs rather than tool pages, calculates CTR from clicks and impressions, and prints up to ten URLs with at least 100 impressions and CTR of 2% or less. Those numbers are editable screening thresholds, not a Google rule or a universal target.

"""Shortlist existing blog URLs from two Search Console Pages CSV exports."""
import csv
import sys

ALIASES = {
    "Top pages": "url", "Páginas principales": "url", "Page": "url",
    "Página": "url", "URL": "url", "Clicks": "clicks", "Clics": "clicks",
    "Impressions": "impressions", "Impresiones": "impressions",
}


def load(path):
    with open(path, encoding="utf-8-sig", newline="") as handle:
        rows = csv.DictReader(handle)
        fields = {ALIASES.get(k.strip(), k.strip()): k for k in rows.fieldnames or []}
        needed = ("url", "clicks", "impressions")
        if any(k not in fields for k in needed):
            raise SystemExit(f"Missing columns in {path}: {needed}; received {rows.fieldnames}")
        data = {}
        for row in rows:
            url = row[fields["url"]].strip()
            if "/blog/" not in url and "/en/blog/" not in url:
                continue
            data[url] = (
                int(row[fields["clicks"]].strip()),
                int(row[fields["impressions"]].strip()),
            )
        return data


def shortlist(current, previous, min_impressions=100, max_ctr=0.02):
    found = []
    for url, (clicks, impressions) in current.items():
        if not impressions or impressions < min_impressions:
            continue
        ctr = clicks / impressions
        if ctr > max_ctr:
            continue
        old_clicks, old_impressions = previous.get(url, (0, 0))
        found.append((impressions, url, clicks, ctr, old_clicks, old_impressions))
    return sorted(found, reverse=True)


if __name__ == "__main__":
    if len(sys.argv) != 3:
        raise SystemExit("Usage: python3 gsc_csv_opportunities.py current.csv previous.csv")
    for impressions, url, clicks, ctr, old_clicks, old_impressions in shortlist(
        load(sys.argv[1]), load(sys.argv[2])
    )[:10]:
        print(f"{impressions:>5} imp | {clicks:>3} clicks | {ctr:.1%} CTR | "
              f"previous {old_impressions} imp/{old_clicks} clicks | {url}")

Run python3 gsc_csv_opportunities.py current.csv previous.csv. The output includes current impressions, clicks, and CTR alongside the previous period. If your CSV uses different column labels, add them to ALIASES; the error prints the headers it received. Keep private Search Console exports on your own machine rather than uploading them to an arbitrary online code runner.

3. Turn the shortlist into an editorial decision

A page with 500 impressions and one click deserves investigation, but this alone does not prove that its headline is weak. Filter the page in Search Console and open Queries. It may rank for questions the article does not answer, sit low in results, or simply be too new. Google's guidance suggests investigating changes by query and page and giving more weight to trends in impressions and clicks than to a single position value.

Diagram: export two CSVs, filter URLs, review queries, and improve the same page
Decision flow; a CTR figure alone does not identify the cause.

Check publication and last-edit dates as well. The Pages CSV does not contain the article's age, so this script cannot automatically exclude yesterday's posts. Wait for comparable complete data and consider pages of similar age. If an established page misses the query intent, improve its title and opening, add the missing example, and keep the URL. If it already answers the query, a low CTR can reflect the search results page rather than a fix you can make in the article.

Local test: I ran the script against sample Spanish and English CSVs. It selected a blog URL with 200 impressions and two clicks, skipped a higher-CTR page and a tool URL, and displayed 50 impressions from the previous period. That tests the selection logic; it is not a claim about real traffic. Confirm your filters, dates, and export coverage before changing a live article.

Frequently asked questions

How can I find blog pages with many impressions but few clicks in Search Console?

Export the Pages table for two complete periods with identical filters, compare impressions and clicks by URL, then review queries for each candidate. Low CTR is a reason to investigate, not proof of a bad headline.

Comentarios

Aún no hay comentarios. Sé el primero.

Deja un comentario