用 Python 做 SEO 分析:自动化数据提取与报告

Python 已经成为 SEO 数据分析与自动化的必备工具。本指南介绍了 SEO 从业者最实用的 Python 脚本和库。

SEO 必备的 Python 库

数据采集

数据处理

可视化

必备的 SEO Python 脚本

脚本 1:GSC 数据提取器

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)

脚本 2:关键词聚类

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

脚本 3:技术 SEO 审计器

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)

脚本 4:SERP 功能追踪器

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)

搭建你的 Python SEO 环境

快速上手

# 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

自动化定时任务

# Run weekly GSC data pull
crontab -e
0 6 * * 1 cd /path/to/seo-scripts && python gsc_extract.py

常见问题

使用 Python 做 SEO,我必须是开发者吗? 不需要。只要你会运行脚本并修改几个变量,就能拉取 Search Console 数据并自动生成报告。从改造现成脚本开始,而不是从零开始编写。

如何把 SEO 数据导入 Python? Search Console API 是主要来源——只需认证一次,随后即可按日期和页面查询点击量、展示量、排名和查询词。在此之上用 pandas 做分析,再配合调度器实现自动化。

适合入门的第一个 SEO 自动化脚本是什么? 一个每周运行的 Search Console 导出脚本,用来标记点击量或 CTR 下滑的页面。它足够简单,能定时运行,并能发现你在手动检查间隙容易遗漏的问题。

Python 能取代 Semrush 这类工具吗? 在数据拉取、分析和定制报告方面,可以——它更便宜且完全可定制。但对于大规模爬取和竞争对手数据库,专业工具仍有其价值。大多数团队会两者并用。