Python for SEO Analysis: Automating Data Extraction and Reporting

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

Data Processing

Visualization

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.