ラッコキーワードをPythonで自作するSEOパイプライン構築術
ラッコキーワードの主要機能であるサジェスト五十音網羅・上位サイト見出し(H1〜H3)抽出・共起語解析は、Pythonの標準ライブラリおよびBeautifulSoupを用いることで、外部有料APIを介さずに完全自作・自動化が可能です。本稿では、当研究所のメディア運用現場で稼働している自前SEOパイプラインの設計思想と実装コードを解説します。
先行して執筆した開発ドキュメンタリーおよび思考プロセスは、公式note ラッコキーワードの全機能をPythonで自作してみた話 でも詳しく公開していますが、本稿ではエンジニアリングとシステムアーキテクチャの観点から、その具体的な設計仕様を深掘りします。
ラッコキーワードの機能構造と自前実装スタック比較
Webメディア運営において必須とされるキーワードリサーチですが、ツールの裏側で実行されている処理を分解すると、その多くは軽量なHTTPリクエストとHTMLパースで構成されています。
当研究所で構築した自前パイプラインと、一般的な商用ツールの実装スタックの対比は以下の通りです。
| 機能項目 | 商用ツールの裏側ロジック | 自前パイプラインの実装方式 |
|---|---|---|
| サジェストキーワード取得 基本機能 | Google等のオートコンプリートAPIへの総当たりクエリ | urllib / requests 五十音+A-Zのループ処理(0円・秒速数百件) |
| 上位サイト見出し抽出 構成分析 | SERPスクレイピング+DOM解析 | Playwright / BeautifulSoup H1〜H3タグのツリー抽出とMarkdown構造化 |
| 共起語・頻出語カウント 形態素解析 | 本文テキストの分かち書き集計 | Janome / MeCab ストップワード除外と品詞別頻度ランキング算出 |
| 月間検索ボリューム判定 数値データ | Google広告APIまたはサードパーティ再販 | Ubersuggest API連携 特定重要KWのみピンポイント抽出(コスト最小化) |
自前パイプラインの3大コアモジュール設計
システムは大きく分けて3つの独立したモジュールで構成されています。各モジュールが疎結合に設計されているため、CLIツールとしても、Webバックエンドとしても容易に再利用が可能です。
Googleサジェストの公開エンドポイントに対し、シードキーワードへ五十音(あ〜ん)およびアルファベット(a〜z)を順次結合した非同期リクエストを送信。重複を排除した一意のキーワードセットを生成します。
検索結果上位10サイトのURLを取得し、メインコンテンツ領域からH1・H2・H3タグを再帰的に抽出。競合サイトの見出し構造を階層ツリーとしてMarkdown形式で即時出力します。
抽出された数百のサジェスト群から、指定条件(例:単語数2語以上、除外ワードを含まない等)に合致する候補を抽出し、Ubersuggest APIを叩いて月間検索数(Volume)と難易度(SD)を付与します。
Googleサジェスト自動取得スクリプトの実装例
以下は、Googleサジェストを自動巡回して五十音順に整理するPythonのコアスクリプトです。外部ライブラリに依存せず、Python標準環境のみで即座に動作します。
import urllib.request
import json
import urllib.parse
import time
def fetch_suggest(query: str) -> list[str]:
encoded = urllib.parse.quote(query)
url = f"https://suggestqueries.google.com/complete/search?client=chrome&hl=ja&q={encoded}"
req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})
try:
with urllib.request.urlopen(req, timeout=5) as res:
data = json.loads(res.read().decode("utf-8"))
return data[1] if len(data) > 1 else []
except Exception:
return []
def collect_all_suggests(seed_keyword: str) -> list[str]:
results = set(fetch_suggest(seed_keyword))
# ひらがな50音 + アルファベット
chars = [chr(i) for i in range(ord("ぁ"), ord("ん")+1)] + [chr(i) for i in range(ord("a"), ord("z")+1)]
for char in chars:
sub_query = f"{seed_keyword} {char}"
for item in fetch_suggest(sub_query):
results.add(item)
time.sleep(0.2) # サーバー負荷への配慮
return sorted(list(results))
上位サイト見出し抽出とInformation Gainの算出
競合上位サイトの構成を把握する最大の目的は、「同じ構成を真似ること」ではありません。Googleの特許アルゴリズム(US10725986B2)が規定する Information Gain(情報利得スコア) を最大化するために、「競合上位10サイトの誰も触れていない情報の空白地帯」 を特定することにあります。
自前スクリプトによって出力された見出し一覧を言語モデル(LLM)に入力し、以下の分析を自動実行させます。
- 共通項の特定:上位サイトが100%記載している「読者の前提知識」を抽出する。
- 独自要素の逆算:上位サイトが触れていない「具体的な実測数値」「現場での失敗リスク」「当事者の生々しいペイン」を空白スロットとして自動設計する。
自前パイプラインを「インハウス運用」に限定する戦略的理由
本システムを一般的なWebサービスとして一般公開しない理由は、運用コストの観点のみならず、Googleの品質評価基準(E-E-A-T)に基づく明確な戦略的判断によるものです。
第一に、他社の公開エンドポイントやスクレイピングデータを右から左へ流すだけのWebツールは、検索エンジンから「付加価値のない薄いコンテンツ」と判定されるリスクが極めて高い点が挙げられます。
第二に、本当にメディアの競争力となるのは「ツールそのもの」ではなく、「ツールによって節約された膨大な時間を使って、現場の一次体験や実測検証にリソースを集中させること」だからです。
道具に使われる受動的な立場から脱却し、必要な仕組みを自らの手でコードに落とし込むことこそが、急激に変化するAI・SEO時代における最大の防御策となります。


