去年我在清迈的咖啡馆写代码,收到一个邮件:“帮我们监测 5 个国家的 Google 排名,预算有限。” 我本来想拒的——5 个国家意味着 5 套代理、5 种语言屏蔽、5 倍的维护量。后来用了一个取巧的方案,一个人搞定了传统团队三个人才能干的活。

一、项目背景:一个人管 5 个国家

客户是一家跨境工具 SaaS,主要市场在美、英、德、法、日。需求:

  • 1200 个关键词
  • 每个关键词查前 50 条结果
  • 覆盖 5 个国家
  • 每周出一次排名报告
  • 预算很低

翻译一下:1200 × 50 × 5 = 30 万条结果/周,大概需要 6000 次 API 请求(一次请求拿 50 条)。预算有限意味着我不能上企业级方案。

二、传统方案的问题

一开始我想的是老路子:

  1. 买 5 台 VPS(各国一个节点)
  2. 每台搭代理池
  3. 部署分布式爬虫
  4. 统一汇总数据

算了一笔账:

项目 成本
5 台 VPS ~$150/月
住宅代理 5 国 ~$500/月
爬虫维护(人时) 每周至少 10 小时
验证码打码 ~$50/月
总计 ~$700+/月

客户给的预算是 $300/月。这账算下来根本接不了。

后来朋友说:“你试试 SerpBase 呗,gl 参数直接选国家,一个 API 搞定所有地区。”

三、方案设计:一个 API 撑起全链路

3.1 架构

关键词列表 (1200个)
    |
    ↓
调度器 (Python APScheduler)
    |
    ↓
SerpBase API (gl=us, gl=gb, gl=de, gl=fr, gl=jp)
    |
    ↓
解析器 (提取排名+URL+摘要)
    |
    ↓
CSV/Excel 报告 + Google Sheets 看板

所有区别只有 gl 参数:

COUNTRIES = {
    "us": "美国 (English)",
    "gb": "英国 (English)",
    "de": "德国 (Deutsch)",
    "fr": "法国 (Français)",
    "jp": "日本 (日本語)"
}

3.2 采集核心

import requests
import csv
import time
from datetime import datetime
from concurrent.futures import ThreadPoolExecutor, as_completed

class MultiCountrySEOCollector:
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.base_url = "https://api.serpbase.dev/google/search"
    
    def fetch_country(self, keyword: str, gl: str) -> dict:
        headers = {
            "X-API-Key": self.api_key,
            "Content-Type": "application/json"
        }
        body = {"q": keyword, "gl": gl, "hl": "en" if gl != "jp" else "ja", "page": 1}
        resp = requests.post(self.base_url, headers=headers, json=body, timeout=30)
        return {
            "keyword": keyword,
            "country": gl,
            "data": resp.json(),
            "timestamp": datetime.utcnow().isoformat()
        }
    
    def collect_all(self, keywords: list, countries: list):
        results = []
        tasks = []
        
        with ThreadPoolExecutor(max_workers=3) as executor:
            for kw in keywords:
                for gl in countries:
                    tasks.append(executor.submit(self.fetch_country, kw, gl))
                    time.sleep(0.4)  # 限流
            
            for future in as_completed(tasks):
                results.append(future.result())
        
        return results
    
    def extract_rank(self, result: dict, domain: str) -> dict:
        organic = result["data"].get("organic", [])
        rank = 999
        snippet = ""
        for item in organic:
            if domain in item.get("link", ""):
                rank = item.get("rank", 999)
                snippet = item.get("snippet", "")
                break
        
        return {
            "keyword": result["keyword"],
            "country": result["country"],
            "rank": rank,
            "snippet": snippet,
            "timestamp": result["timestamp"]
        }
    
    def generate_report(self, keywords: list, domain: str):
        raw = self.collect_all(keywords, list(COUNTRIES.keys()))
        rows = []
        for r in raw:
            row = self.extract_rank(r, domain)
            rows.append(row)
        
        with open(f"seo_report_{datetime.now().strftime('%Y%m%d')}.csv", "w", newline="") as f:
            writer = csv.DictWriter(f, fieldnames=["keyword", "country", "rank", "snippet", "timestamp"])
            writer.writeheader()
            writer.writerows(rows)
        
        return rows

# 使用
collector = MultiCountrySEOCollector(api_key="YOUR_KEY")
rows = collector.generate_report(keywords, "client-website.com")

3.3 差异化分析

拿到原始排名还不够,客户要的是洞察。我加了一个对比分析模块:

import pandas as pd

def analyze_position_gaps(df: pd.DataFrame) -> dict:
    """找出各国之间排名差异最大的关键词"""
    pivot = df.pivot_table(index="keyword", columns="country", values="rank", aggfunc="first")
    pivot["max_diff"] = pivot.max(axis=1) - pivot.min(axis=1)
    gaps = pivot.sort_values("max_diff", ascending=False).head(20)
    
    insights = []
    for kw, row in gaps.iterrows():
        best_country = row.drop("max_diff").idxmin()
        worst_country = row.drop("max_diff").idxmax()
        insights.append({
            "keyword": kw,
            "best_country": best_country,
            "best_rank": int(row[best_country]),
            "worst_country": worst_country,
            "worst_rank": int(row[worst_country]),
            "gap": int(row["max_diff"])
        })
    return insights

打一个比方,某个词在美国排第 3 但在德国排第 35,说明德语的 SEO 策略可能需要单独优化。这种"按国别差异"的分析,客户觉得很有价值。

四、最终交付和成本

4.1 交付物

  1. 每周 CSV 报告:1200 词 × 5 国 × 当前排名
  2. Google Sheets 看板:链接到客户已有的 Google Analytics 看板
  3. 差异分析报告:TOP 20 国别差异最大的关键词 + 优化建议

4.2 成本

项目 费用
SerpBase(Business 包 $500,150万次,可用约 3 个月) ~$167/月
轻量服务器(跑定时任务) ¥69/月
总支出 ~$177/月
客户预算 $300/月
利润 ~$123/月

4.3 跟自建方案对比

维度 自建代理方案 SerpBase API 方案
多国覆盖 每国配代理+节点 一个参数搞定
开发周期 2-3 周 3 天
月成本 ~$700+ ~$177
维护负担 几乎为零
利润率

坦白说,没有 SerpBase 这个项目我根本接不了——以客户给的预算,自建方案怎么算都是亏的。

五、一些经验分享

5.1 关于限流策略

多国采集最大的挑战是请求量:1200 词 × 5 国 = 6000 次请求。如果一次性跑,妥妥触发限流。

我的做法是分批跑,每批 200 个词,批次间隔 30 分钟。一周分 3 天跑完,每天 2000 次请求,分布到 8 个小时里,QPS 不到 0.1,完全不会触发限流。

5.2 关于结果一致性

不同时间跑同一个词,Google 结果会有差异。为了让同一周内的数据有可比性,我在一周内固定时间窗口跑(比如每周二和周四的下午 2 点 UTC),尽量减少时间差异引入的噪声。

5.3 关于 hl 和 gl 组合

之前踩过一个坑:gl=jphl=en,返回的结果是日本的搜索结果但界面是英文,有些日文站点的 snippet 被截断或编码异常。后来针对日本市场单独设 hl=ja,问题解决。

六、总结

对独立开发者来说,多国 SEO 数据采集这个需求真实存在,但市场定价已经被拉得很低。靠传统代理+爬虫的路线,成本结构注定做不了低价单。

API 方案让一个人也可以接以前需要一个小团队才能做的活。客户的预算 300 刀,自建要 700 刀是亏的,但用 API 成本 177 刀,净赚 123 刀。这就是信息差和工具差的价值。

如果你也是数字游民或者自由职业者,遇到多国 SEO 项目,别急着搭代理池,先看看 API 方案能不能搞定。说不定三四天写好代码,剩下的时间你已经在下一家咖啡馆写代码了。


后来客户又加了巴西和印度两个市场,代码里多写两个 gl 参数就完事了,零额外维护成本。这就是所谓的"躺着赚钱"吧。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐