Python has become the essential tool for SEO data analysis and automation. This guide covers the most useful Python scripts and libraries for SEO professionals.
Essential Python Libraries for SEO
Data Collection
- google-api-python-client: GSC and GA4 API access
- requests: HTTP requests for scraping and APIs
- selenium: Browser automation for JavaScript sites
Data Processing
- pandas: Data manipulation and analysis
- numpy: Numerical computing
- regex: Pattern matching and text processing
Visualization
- matplotlib: Basic charting
- plotly: Interactive visualizations
- seaborn: Statistical visualizations
Must-Have SEO Python Scripts
Script 1: GSC Data Extractor
from google.oauth2 import service_account
from googleapiclient.discovery import build
import pandas as pd
class GSCExtractor:
def __init__(self, credentials_path):
self.credentials = service_account.Credentials.from_service_account_file(
credentials_path,
scopes=['https://www.googleapis.com/auth/webmasters.readonly']
)
self.service = build('searchconsole', 'v1', credentials=self.credentials)
def get_performance(self, site_url, start_date, end_date, dimensions=['query']):
request = {
'startDate': start_date,
'endDate': end_date,
'dimensions': dimensions,
'rowLimit': 25000,
}
response = self.service.searchanalytics().query(
siteUrl=site_url, body=request
).execute()
rows = []
for row in response.get('rows', []):
data = dict(zip(dimensions, row['keys']))
data.update({
'clicks': row['clicks'],
'impressions': row['impressions'],
'ctr': round(row['ctr'], 4),
'position': round(row['position'], 1)
})
rows.append(data)
return pd.DataFrame(rows)
Script 2: Keyword Clustering
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
import numpy as np
def cluster_keywords(keywords, max_clusters=20):
# Vectorize keywords
vectorizer = TfidfVectorizer(stop_words='english', ngram_range=(1, 3))
X = vectorizer.fit_transform(keywords)
# Find optimal number of clusters
best_score = -1
best_k = 2
for k in range(2, min(max_clusters, len(keywords) // 5 + 1)):
kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
labels = kmeans.fit_predict(X)
score = silhouette_score(X, labels)
if score > best_score:
best_score = score
best_k = k
# Final clustering
kmeans = KMeans(n_clusters=best_k, random_state=42, n_init=10)
labels = kmeans.fit_predict(X)
# Create output
clusters = {}
for keyword, label in zip(keywords, labels):
if label not in clusters:
clusters[label] = []
clusters[label].append(keyword)
return clusters
Script 3: Technical SEO Auditor
import requests
from urllib.parse import urljoin, urlparse
from bs4 import BeautifulSoup
import time
class TechnicalSEOAuditor:
def __init__(self, base_url):
self.base_url = base_url
self.visited = set()
self.issues = []
def audit_page(self, url):
if url in self.visited:
return
self.visited.add(url)
try:
response = requests.get(url, timeout=10)
soup = BeautifulSoup(response.text, 'html.parser')
# Check title tag
title = soup.find('title')
if not title:
self.issues.append({'url': url, 'issue': 'Missing title tag'})
elif len(title.text) > 60:
self.issues.append({'url': url, 'issue': 'Title tag too long', 'value': title.text})
# Check meta description
meta_desc = soup.find('meta', attrs={'name': 'description'})
if not meta_desc:
self.issues.append({'url': url, 'issue': 'Missing meta description'})
# Check H1 tag
h1 = soup.find('h1')
if not h1:
self.issues.append({'url': url, 'issue': 'Missing H1 tag'})
elif len(soup.find_all('h1')) > 1:
self.issues.append({'url': url, 'issue': 'Multiple H1 tags'})
# Check images for alt text
images = soup.find_all('img')
for img in images:
if not img.get('alt'):
self.issues.append({'url': url, 'issue': 'Image missing alt text', 'value': img.get('src', '')})
# Check canonical
canonical = soup.find('link', attrs={'rel': 'canonical'})
if not canonical:
self.issues.append({'url': url, 'issue': 'Missing canonical tag'})
except requests.RequestException as e:
self.issues.append({'url': url, 'issue': f'Request error: {str(e)}'})
def get_issues_report(self):
return pd.DataFrame(self.issues)
Script 4: SERP Feature Tracker
def track_serp_features(keywords, api_key):
results = []
for keyword in keywords:
serp_data = get_serp_data(keyword, api_key)
features = {
'keyword': keyword,
'featured_snippet': False,
'people_also_ask': False,
'image_pack': False,
'video_carousel': False,
'local_pack': False,
'knowledge_panel': False,
'shopping_results': False,
'ai_overview': False,
}
for feature in serp_data.get('features', []):
if feature in features:
features[feature] = True
results.append(features)
return pd.DataFrame(results)
Setting Up Your Python SEO Environment
Quick Start
# Create virtual environment
python -m venv seo-tools
source seo-tools/bin/activate
# Install essential packages
pip install google-api-python-client pandas numpy scikit-learn beautifulsoup4 requests plotly
# Create project structure
mkdir seo-scripts
mkdir seo-scripts/data
mkdir seo-scripts/output
Automated Scheduling
# Run weekly GSC data pull
crontab -e
0 6 * * 1 cd /path/to/seo-scripts && python gsc_extract.py
Frequently asked questions
Do I need to be a developer to use Python for SEO? No. If you can run a script and edit a few variables, you can pull Search Console data and automate reports. Start by adapting an existing script rather than writing one from scratch.
How do I get SEO data into Python? The Search Console API is the main source — authenticate once, then query clicks, impressions, position, and queries by date and page. From there it's pandas for analysis and a scheduler for automation.
What's a good first SEO automation script? A weekly Search Console export that flags pages with falling clicks or CTR. It's simple, runs on a schedule, and surfaces issues you'd otherwise miss between manual checks.
Can Python replace tools like Semrush? For data pulling, analysis, and custom reporting, yes — it's cheaper and fully customizable. For crawling at scale and competitive databases, dedicated tools still earn their keep. Most teams use both.