Free SEO audit for new clients — claim yours
Home/Blog/Technical SEO/Python for SEO: Beginner Scripts That Save Hours
Technical SEO

Python for SEO: Beginner Scripts That Save Hours

Python for SEO: Beginner Scripts That Save Hours
Table of contents
  1. Why marketers reach for Python instead of another spreadsheet
  2. Setting up Python without the usual headaches
  3. Script one: bulk status code and redirect checker
  4. Script two: pulling Search Console data past the 1,000-row ceiling
  5. Script three: grouping keywords by similarity with built-in Python
  6. A worked example: one Monday morning, three scripts
  7. Using AI assistants to write and debug scripts safely
  8. Questions beginners ask about Python for SEO
    1. Do I need to learn programming properly before using Python for SEO?
    2. Is Python better than Google Sheets or Apps Script for SEO tasks?
    3. Why does the Search Console API return fewer rows than I expect?
    4. Is it safe to paste my scripts into ChatGPT or Claude?
    5. Will running a status code checker harm my site?
  9. Your first week of SEO scripting
  10. Further reading on python for seo
  11. Sources for this Python for SEO guide

Every SEO has a task they do by hand that they know a computer should be doing. Checking where 400 old URLs redirect after a migration. Exporting Search Console data 1,000 rows at a time because the interface will not give you more. Sorting 3,000 keywords into groups in a spreadsheet, row by row. These jobs are boring, error-prone and repeated every month.

Python is the most common way marketers automate them, not because it is fashionable, but because it reads almost like English, it has well-maintained libraries for web requests and data tables, and an AI assistant can explain any line you do not understand. You do not need to become a developer. You need to be able to run three or four short scripts and adapt them.

This guide is a gentle start for non-developers. It covers a headache-free setup, then three complete scripts you can run today: a bulk status code and redirect checker, a Search Console API export that gets past the interface limit, and a keyword grouper that uses only built-in Python. It ends with how to use AI assistants to write and debug scripts without creating security problems.

Why marketers reach for Python instead of another spreadsheet

Spreadsheets are excellent until the data gets wide, long or repetitive. Python earns its place when a task has one of these traits:

  • Volume: thousands of URLs or keywords, where formulas slow down or browser extensions time out.
  • Network calls: fetching pages or calling APIs, which spreadsheets do clumsily.
  • Repetition: the same export and clean-up every week or month.
  • Joining sources: combining a crawl, a Search Console export and an analytics export by URL.
TaskManual time (rough)Scripted timeBest tool
Check status and redirect target of 500 URLsHours with a browserA few minutesPython or a crawler
Export page + query data beyond 1,000 rowsNot possible in the interfaceMinutes via APIPython, Sheets add-on or BigQuery
Group 3,000 keywords by similarityA day of sortingSecondsPython
Monthly report table for one clientAn hourMinutesSheets or a dashboard
One-off check of a single pageSecondsNot worth scriptingBrowser

The time estimates are illustrative, but the pattern holds: scripting pays off for anything large or repeated. If your work is mostly light formulas and sharing, our guide to Google Sheets for marketers may be the better first step.

Setting up Python without the usual headaches

Most beginner frustration comes from setup, not code. Follow this sequence once and you will avoid the classic “module not found” and “python is not recognised” errors.

  1. Install Python 3 from python.org. On Windows, tick the box to add Python to PATH on the first installer screen. On a Mac, use the python.org installer rather than relying on any system copy.
  2. Create a project folder, for example seo-scripts, and open a terminal in it (on Windows, type cmd in the folder’s address bar; on a Mac, right-click the folder in Finder and choose New Terminal at Folder).
  3. Create a virtual environment: python -m venv .venv (use python3 on a Mac). This keeps each project’s packages separate.
  4. Activate it: .venv\Scripts\activate on Windows or source .venv/bin/activate on a Mac. Your prompt now shows (.venv).
  5. Install packages: pip install requests pandas google-api-python-client google-auth.
  6. Use a simple editor, such as VS Code with the Python extension. Save scripts as .py files in the project folder and run them with python script_name.py.

If you prefer not to install anything, Google Colab runs Python notebooks in the browser. It is fine for the keyword and API scripts, but keep service-account keys out of shared notebooks.

Script one: bulk status code and redirect checker

This is the script to run before and after every migration, and whenever someone hands you a list of URLs and asks “are these working?”. Put one URL per line in urls.txt, then run:

import csv
import requests

HEADERS = {"User-Agent": "Mozilla/5.0 (compatible; MySEOChecker/1.0)"}

with open("urls.txt", encoding="utf-8") as f:
    urls = [line.strip() for line in f if line.strip()]

with open("redirect_report.csv", "w", newline="", encoding="utf-8") as out:
    writer = csv.writer(out)
    writer.writerow(["url", "first_status", "hops", "final_url", "final_status", "chain"])
    for url in urls:
        try:
            r = requests.get(url, headers=HEADERS, timeout=15, allow_redirects=True)
            chain = [resp.status_code for resp in r.history] + [r.status_code]
            writer.writerow([url, chain[0], len(r.history), r.url, r.status_code,
                             " > ".join(str(c) for c in chain)])
        except requests.RequestException as e:
            writer.writerow([url, "error", "", "", "", type(e).__name__])
        print("checked", url)

What it does, line by line in plain terms: it reads your URL list; requests each URL and follows redirects; records every status code in the chain (for example 301 > 301 > 200); and writes the first status, number of hops, final URL and final status to redirect_report.csv. Errors such as timeouts are recorded rather than crashing the script.

How to read the output:

Pattern in the reportMeaningAction
first_status 301, hops 1, final 200Clean permanent redirectNone
hops 2 or moreRedirect chainPoint the first URL straight at the final one
first_status 302 or 307 on a permanent moveTemporary redirectChange to 301 or 308
final_status 404 or 410Redirect to a dead page, or deleted pageFix mapping, or confirm deletion was intended
first_status 200 on a URL that should redirectMissing redirect, or a client-side oneCheck the HTML for meta refresh or JavaScript
first_status 5xxServer errorEscalate; Google slows crawling on 5xx

One limitation matters: the requests library only follows server-side redirects. A 200 response that redirects with a meta refresh or JavaScript will show as 200. Our guide to meta refresh and JavaScript redirects explains how Google treats those, and Google’s redirects documentation lists which methods it treats as permanent.

Script two: pulling Search Console data past the 1,000-row ceiling

The Performance report in Search Console shows at most 1,000 rows in the interface. The Search Analytics API returns far more per request, which used to be 5,000 rows:

“With the GSC API, the maximum page size is 25,000 rows (the default is 1,000).”

— Analytics Edge, Download Over 25,000 Rows From Google Search Console API

Search Engine Land reported the change from 5,000 to 25,000 rows per request when Google introduced it. To get more than 25,000 rows, you request the next “page” of results with the startRow parameter until a page comes back short.

One-time setup (about 15 minutes):

  1. In Google Cloud Console, create a project and enable the Google Search Console API.
  2. Create a service account and download its JSON key into your project folder as service-account.json. Treat this file like a password.
  3. In Search Console, add the service account’s email address as a user on the property (restricted access is enough for reading data). Our Search Console property setup guide covers users and permissions.
  4. Use sc-domain:example.com for a Domain property or the full URL with trailing slash for a URL-prefix property.
import pandas as pd
from google.oauth2 import service_account
from googleapiclient.discovery import build

SITE = "sc-domain:example.com"          # or "https://www.example.com/"
KEY_FILE = "service-account.json"
SCOPES = ["https://www.googleapis.com/auth/webmasters.readonly"]

creds = service_account.Credentials.from_service_account_file(KEY_FILE, scopes=SCOPES)
service = build("searchconsole", "v1", credentials=creds)

rows, start_row, page_size = [], 0, 25000
while True:
    body = {
        "startDate": "2026-07-01",
        "endDate": "2026-09-30",
        "dimensions": ["page", "query"],
        "type": "web",
        "rowLimit": page_size,
        "startRow": start_row,
    }
    resp = service.searchanalytics().query(siteUrl=SITE, body=body).execute()
    batch = resp.get("rows", [])
    rows.extend(batch)
    if len(batch) < page_size:
        break
    start_row += page_size

df = pd.DataFrame([
    {"page": r["keys"][0], "query": r["keys"][1], "clicks": r["clicks"],
     "impressions": r["impressions"], "ctr": r["ctr"], "position": r["position"]}
    for r in rows
])
df.to_csv("gsc_page_query.csv", index=False)
print(len(df), "rows saved")

This pulls page-and-query rows for a quarter and saves them to a CSV you can open in Excel or Sheets. Change the dimensions list to ["query"], ["page"], ["date"] or add "country" and "device" as needed.

Know the limits before you trust the totals. Third-party write-ups of Google’s documentation describe a daily cap:

“Google Search Console API does not return more than 50,000 rows per day per search type (web, image, video, etc.).”

— Weld, Google Search Console 50k limit
LimitValueReported byWorkaround
Rows per API request25,000 (default 1,000)Analytics Edge, Search Engine LandPage with startRow
Rows per day per search type50,000WeldQuery one day at a time; BigQuery bulk export
Data history16 monthsWindsor.aiSave exports monthly
Data freshnessTypically 2–3 days to settleWindsor.aiExclude the latest days
Queries per minute, per site and per user1,200Windsor.aiAdd a short pause in loops

Analytics Edge adds that results are sorted by clicks with no secondary sort, which can produce duplicated or missing rows across pages, and that anonymised queries are filtered out. So a common technique is to query one day at a time and combine the days. Windsor.ai’s guide also notes that Search Console keeps 16 months of data and that numbers take two to three days to settle, so avoid the most recent days in reports. For very large sites, Google’s bulk data export to BigQuery, announced in February 2023, provides a daily data dump without the row caps; see our guide to BigQuery exports for the analytics side.

Script three: grouping keywords by similarity with built-in Python

Keyword grouping usually means paid tools or embeddings. For a first pass, Python’s standard library is enough. This script needs no installs beyond Python itself. Put your keywords in keywords.csv with a header row and one keyword per line:

import csv
from difflib import SequenceMatcher

def normalise(kw):
    words = kw.lower().replace("-", " ").split()
    return " ".join(sorted(words))

def similar(a, b):
    return SequenceMatcher(None, a, b).ratio()

keywords = [row[0] for row in csv.reader(open("keywords.csv", encoding="utf-8"))][1:]
groups = []          # each group: [label, [keywords]]
THRESHOLD = 0.75

for kw in keywords:
    key = normalise(kw)
    for group in groups:
        if similar(key, group[0]) >= THRESHOLD:
            group[1].append(kw)
            break
    else:
        groups.append([key, [kw]])

with open("keyword_groups.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.writer(f)
    writer.writerow(["group", "keyword"])
    for label, members in groups:
        for kw in members:
            writer.writerow([members[0], kw])

print(f"{len(keywords)} keywords grouped into {len(groups)} groups")

The trick is in normalise(): lowercasing and sorting the words means “london emergency plumber” and “emergency plumber london” become the same string, so word order no longer matters. SequenceMatcher then scores how similar two strings are between 0 and 1, which catches plurals and small variations.

We tested it on a ten-keyword sample. It produced five groups: the three “emergency plumber london” variants together, the three “boiler repair cost” variants (including “cost of boiler repair” and “boiler repair costs uk”) together, “blocked drain” with “blocked drains”, and “unblock drain” and “plumber near me” on their own.

  • Raise THRESHOLD (towards 0.85) for tighter, smaller groups.
  • Lower it (towards 0.65) for broader groups, at the risk of merging different intents.
  • Remember the limit: this is lexical similarity. “Unblock drain” and “blocked drain” may share intent, but the strings are not similar enough to group. For intent-level clustering, compare search results or use embeddings, as discussed in our keyword clustering guide.

A worked example: one Monday morning, three scripts

A hypothetical scenario. An agency has just migrated a client from an old CMS. It has 640 old URLs from the previous sitemap, a Search Console property and a keyword list of 2,100 terms for the next content plan.

  1. 09:00: run the redirect checker on the 640 URLs. The report shows 590 clean 301s, 31 chains of two hops, 12 redirects landing on 404s and 7 URLs still returning 200. That is 50 fixes, prioritised by which URLs had organic clicks.
  2. 09:20: run the Search Console script for the 90 days before launch, with page as the dimension, and join it to the redirect report in Excel or pandas. Two of the 12 broken redirects turn out to be among the top 20 landing pages. They are fixed first.
  3. 09:40: run the keyword grouper on 2,100 terms. At 0.75 it returns several hundred groups; the writer reviews the 50 largest and maps them to existing or planned pages.

Total hands-on time is under an hour for work that would previously take most of a day. On much bigger sites, the same approach scales with sampling and log data; see large-site SEO.

Using AI assistants to write and debug scripts safely

AI assistants are the reason Python is now realistic for non-developers. They are very good at explaining errors, adding features to working scripts and converting a description into a first draft. They also make confident mistakes. A safe working pattern:

  1. Describe inputs and outputs precisely: “Read urls.txt, one URL per line; write a CSV with columns url, status, final_url.”
  2. Ask for comments on every block so you can follow what it does.
  3. Run on five rows first, and check the output by hand against a browser or Search Console.
  4. Paste the full error message when something fails, along with the script, and ask what caused it and how to fix it.
  5. Never paste secrets. Replace keys, passwords and service-account contents with placeholders.
  6. Check library names and API fields against official documentation, because invented parameter names are a common AI error.
  7. Keep working versions in a folder or a Git repository so you can roll back.

Our library of ChatGPT and Claude prompts for SEO includes prompts for script writing. When the scripts become part of a team’s release process, share them with developers using the checklist in SEO for developers.

Questions beginners ask about Python for SEO

Do I need to learn programming properly before using Python for SEO?

No. Most useful SEO scripts are 20–50 lines: read a list, call a website or API, write a CSV. Learn to run a script, install a package and read an error message, and you can adapt existing scripts. Deeper skills come from fixing real problems.

Is Python better than Google Sheets or Apps Script for SEO tasks?

They overlap. Sheets is better for sharing and light formulas; Python is better for thousands of URLs, API pagination, joining large files and anything you want to repeat on a schedule. Many teams pull data with Python and present it in Sheets or a dashboard.

Why does the Search Console API return fewer rows than I expect?

Two limits apply. Each request returns at most 25,000 rows, so you must page with startRow. And third-party documentation of Google’s limits reports a cap of 50,000 rows per day per search type, with anonymised queries filtered out, so very large sites will not get every query. For complete data, use the BigQuery bulk export.

Is it safe to paste my scripts into ChatGPT or Claude?

Scripts themselves are usually fine. Never paste API keys, service-account JSON files, passwords or client data you are not allowed to share. Replace them with placeholders before asking for help.

Will running a status code checker harm my site?

Not at modest speed. The scripts here make one request at a time. If you check tens of thousands of URLs, add a short pause between requests and run during quiet hours, especially on smaller servers.

Your first week of SEO scripting

Day one: install Python, create a virtual environment and run the redirect checker on ten URLs. Day two: set up a service account and pull a month of Search Console data. Day three: group a keyword list and compare it with your existing pages. By the end of the week you will have three reusable tools and, more importantly, the confidence to adapt them.

If you would rather have the analysis without the scripting, our SEO team runs these checks as part of audits and migrations. Request a free quote and tell us what you need automated.

Further reading on python for seo

Sources for this Python for SEO guide

  1. Analytics Edge: Download over 25,000 rows from Google Search Console API
  2. Weld: The Google Search Console 50k row limit (2025)
  3. Windsor.ai: Guide to the Google Search Console API (updated September 2026)
  4. Search Engine Land: Search Analytics API now gives you 25,000 rows per request
  5. Google Search Central Blog: Bulk data export (February 2023)
  6. Google Search Central: Redirects and Google Search
  7. Google Search Central: HTTP status codes and network errors
Rohit Choudhary
Written byRohit ChoudharyCo-Founder, My SEO Experts

Rohit Choudhary is the co-founder of My SEO Experts and has more than 14 years of hands-on experience in SEO, paid advertising and digital marketing. Since starting out in 2011 he has helped hundreds of businesses grow through practical, data-driven search strategies, and he also serves as a consulting Digital Marketing Director for several US-based companies.

Keep reading

Related articles

How to Run an SEO Audit With Claude and the Semrush MCP
Technical SEO

How to Run an SEO Audit With Claude and the Semrush MCP

A practical workflow for connecting Claude to Semrush data, auditing crawl health, on-page issues, backlinks and competitors, and turning AI findings into a verified, ranked fix list.

Ready to grow your business online?

Get a free, no-obligation proposal tailored to your goals and budget.

CallFree Quote