Claude Codeでブログ作業を自動化した10のこと|スクリプト実名と時短効果を全公開

この記事は 約32分 で読めます
目次
  1. ブログ自動化の全体像 — スクリプト30個超で月25本を回す仕組み
  2. 【1】記事下書きからWordPress自動投稿(publish_post.py)
  3. 【2】アイキャッチ画像の自動生成(generate_eyecatch.py)
  4. 【3】X投稿の自動生成・投稿(generate_x_posts.py + post_x_posts.py)
  5. 【4】ブログ全体の健全性チェック(blog_health_check.py)
  6. 【5】投稿直後の異常チェック(post_health_check.py)
  7. 【6】内部リンクの自動候補抽出(update_internal_links.py)
  8. 【7】KWボリューム調査(research_keyword.py)
  9. 【8】リライト効果測定(track_rewrite_effect.py)
  10. 【9】毎日の巡回監視(patrol_collect.py)
  11. 【10】セッションログの自動チェック(auto_log.py)
  12. 10個を組み合わせて月25本ペースを実現している話
  13. まとめ — 自動化は「全部やるか、やらないか」ではない
  14. よくある質問
  15. Q1. プログラミングができなくてもスクリプトは作れますか?
  16. Q2. 10個の自動化をすべて揃えるのにいくらかかりますか?
  17. Q3. まず1つだけ始めるなら何がおすすめですか?
  18. さいごに

ブログを運営していると、記事を書くこと以外の作業が意外と多い、と感じたことはありませんか。

WordPress に貼り付ける・アイキャッチを作る・X で告知する・サイトが壊れていないか確認する・どの記事が伸びているか追う。これらの作業を記事1本ごとに繰り返していると、週に数時間があっという間に消えていきます。

私はもともと看護師で、プログラミングの経験はゼロでした。それでも Claude Code とスクリプト30個超を組み合わせることで、今は月25本ペースでブログを回せるようになっています。

この記事では、私が実際に使っている10個の自動化を、スクリプト名・実行コマンド・自動化前後の時間・Claude Code への指示文・ハマった点つきで全公開します。「どこから手をつけていいかわからない」という方の参考になれば嬉しいです。

ブログ自動化の全体像と5ステップのフローについては、先に「AIでブログ運営を自動化する5ステップ」を読んでいただくと、この記事の10項目がどこに位置づけられるか掴みやすいと思います。

ブログ自動化の全体像 — スクリプト30個超で月25本を回す仕組み

自動化を始める前、私のブログ作業は「書く」だけのはずなのに、実際には記事1本あたり2〜3時間かかっていました。内訳はこうです。

  • WordPress に手貼り・カテゴリ設定:30分
  • アイキャッチをCanvaで作る:20〜30分
  • X に告知文を考えて投稿:15分
  • 公開後に画像が壊れていないかブラウザ確認:10分

記事を書く時間とほぼ同じ時間を、「書く以外の作業」に使っていたわけです。

Claude Code を使い始めてから、これらの作業を少しずつスクリプト化していきました。今では30個超のスクリプトが存在していて、次の4カテゴリで整理できます。

カテゴリ 自動化している内容 主なスクリプト
制作系 アイキャッチ生成、KW調査 generate_eyecatch.py, research_keyword.py
投稿系 WP自動投稿、frontmatterバリデーション publish_post.py, parse_post.py
発信系 X投稿生成・スケジュール・実行 generate_x_posts.py, post_x_posts.py, daily_x_runner.py
保守系 健全性チェック、巡回監視、リライト効果測定、内部リンク blog_health_check.py, patrol_collect.py, track_rewrite_effect.py, update_internal_links.py

この10個の自動化がどう連鎖するかは、後半の「10個を組み合わせて月25本ペースを実現している話」でまとめます。

【1】記事下書きからWordPress自動投稿(publish_post.py)

スクリプト: publish_post.py / 補助: parse_post.py

やっていること: Markdown ファイルの frontmatter を読み取り、WordPress REST API 経由で投稿・更新する。新規投稿と既存記事のリライト更新(--update {post_id})の両方に対応。

Claude Code への指示文例:

publish_post.py を作って。

Markdown ファイルのパスを引数で受け取り、
YAMLフロントマターから title / slug / seo_title / seo_description /
excerpt / categories / tags / eyecatch を読み取って、
WordPress REST API(Basic認証)で新規投稿するスクリプト。

--update {post_id} オプションを付けると既存記事の更新になるようにして。
.env に WP_BASE_URL / WP_USERNAME / WP_APP_PASSWORD を置く形で。
frontmatter の必須項目が欠けていたらエラーで止めて。
本文中に「品質審査」「タイトル案」などの制作メモが残っていたら
公開前に検出してエラーを出すチェックも入れて。

実行コマンド:

# 新規投稿(下書き状態で投稿)
python -X utf8 scripts/publish_post.py drafts/articles/nurse-first-year-mental/

# 既存記事のリライト更新
python -X utf8 scripts/publish_post.py drafts/articles/nurse-first-year-mental/ --update 2215

frontmatter のサンプル(必須7項目):

---
title: "看護師1年目のメンタル不調"
slug: nurse-first-year-mental
seo_title: "看護師1年目メンタル不調|原因と対処法"
seo_description: "看護師1年目がメンタル不調になる原因と、現役看護師が実践した対処法を解説。"
excerpt: "看護師1年目がメンタル不調になる原因と、現役看護師が実践した対処法を解説。"
categories:
  - 看護師のキャリア
tags:
  - 1年目
  - メンタル
eyecatch: images/nurse-first-year-mental_eyecatch.png
---

Before/After:

指標 自動化前 自動化後
所要時間 30分/記事 1分/記事
主な作業 管理画面でコピペ・カテゴリ選択・タグ入力 コマンド1発

内部的には次のような流れで動いています。

# publish_post.py の処理概要(擬似コード)
front_matter = parse_post.parse_front_matter(md_file)   # YAMLを解析
parse_post.validate_fields(front_matter)                  # 必須項目チェック
parse_post.check_production_meta_contamination(body)      # 制作メモの混入チェック

response = requests.post(
    f"{WP_BASE_URL}/wp-json/wp/v2/posts",
    json={"title": title, "content": html_body, ...},
    auth=HTTPBasicAuth(WP_USERNAME, WP_APP_PASSWORD)
)

ハマった点①: categories の書き方

category: (単数形・文字列)で書くとエラーになります。categories: (複数形・YAMLリスト形式)が必須です。

# NG: 単数形・文字列
category: 看護師のキャリア

# OK: 複数形・リスト形式
categories:
  - 看護師のキャリア

ハマった点②: parse_post.py の制作メモ検出

本文中に「品質審査」「タイトル案」「v2修正」などの制作作業用の語句が残っていると、check_production_meta_contamination() がエラーで止めます。これは意図的な設計で、制作メモが本番公開されるのを防ぐためです。2026年4月の公開事故(制作メモが本文末に残ったまま公開された)を受けて追加したガードです。

この仕組みの詳しい作り方は「MarkdownをWordPressに自動投稿する方法」で解説予定です。

【2】アイキャッチ画像の自動生成(generate_eyecatch.py)

スクリプト: generate_eyecatch.py

やっていること: 06_eyecatch_spec.md に書かれたプロンプトと、あらかじめ用意したアバター参照画像を OpenAI gpt-image-2 API に渡して、1536×1024 の横長アイキャッチ画像を生成する。

Claude Code への指示文例:

generate_eyecatch.py を作って。

06_eyecatch_spec.md のパスを引数で受け取り、
ファイル内の「## プロンプト本体」以下のテキストを読み取って、
assets/avatar/base_avatar.png をアバター参照画像として添付した上で、
OpenAI の gpt-image-2 API(images.edit)に送信する。

サイズは 1536x1024、quality は high、出力先は
drafts/articles/{slug}/images/{slug}_eyecatch.png に自動で保存して。
.env に OPENAI_API_KEY を置く形で。

実行コマンド:

python -X utf8 scripts/generate_eyecatch.py drafts/articles/nurse-first-year-mental/06_eyecatch_spec.md

出力先は drafts/articles/{slug}/images/{slug}_eyecatch.png に自動で保存されます。

eyecatch_spec.md の最小サンプル:

## プロンプト本体
青いスクラブを着た女性看護師が、朝の病棟廊下を歩いているシーン。
自然光が差し込む明るい雰囲気。アニメ調イラスト・淡い彩色。

この ## プロンプト本体 の下に書いた内容が、アバター参照ヘッダーと結合されて API に送られます。

Before/After:

指標 自動化前 自動化後
所要時間 20〜30分/記事(Canva) 30秒〜1分/記事
費用 無料(時間コスト大) 1枚数十円(月8本で200〜300円/月)

ハマった点: アバターの一貫性を保つには参照画像が必要

gpt-image-2 はテキストだけでも画像生成できますが、毎回違う顔の人物が生成されます。base_avatar.png(固定のアバター画像)を image パラメータに渡すことで、ブログのアイキャッチに登場する人物を統一できます。

# generate_eyecatch.py の API 呼び出し部分
with open(AVATAR_PATH, "rb") as f:
    result = client.images.edit(
        model="gpt-image-2",
        image=f,            # 参照アバター画像
        prompt=prompt,      # eyecatch_spec.md のプロンプト
        size="1536x1024",
        quality="high",
        n=1,
    )

また、直近3記事と構図・場所・時間帯を2要素以上ずらすルールを設けています。同じ構図が並ぶとブログとして単調に見えるためです。

この仕組みの詳しい作り方は「AIアイキャッチを gpt-image-2 で作る完全手順」で解説予定です。

【3】X投稿の自動生成・投稿(generate_x_posts.py + post_x_posts.py)

スクリプト: generate_x_posts.py / 補助: post_x_posts.py, daily_x_runner.py

やっていること: 公開済み記事から B1〜B5 の5パターンのX投稿文を自動生成し、承認後に X API v2 経由で投稿する。daily_x_runner.py が毎日5スロット(7時・12時・17時・21時・23時)に割り当てて運用する。

Claude Code への指示文例:

generate_x_posts.py を作って。

Markdown 記事ファイルのパスを引数で受け取り、
記事タイトル・本文・URLをもとに Claude API を呼んで
B1〜B5 の5パターンのX投稿文を生成する。

B1: 体験入口型(「こんなことがあった」から始める)
B2: 学び直球型(「○○には△△が大事」)
B3: 問いかけ型(読者に問いを投げる)
B4: 余韻型(感情・情景で終わる)
B5: 記事告知型(URL直球でブログへ誘導)

生成結果は drafts/x_posts/{slug}.md に保存して。
--from-wp オプションで WordPress の全公開記事を一括処理できるようにして。

実行コマンド:

# done/ フォルダの特定記事からX投稿文を生成
python -X utf8 scripts/generate_x_posts.py done/nurse-first-year-mental_v3.md

# WordPress の全公開記事から一括生成
python -X utf8 scripts/generate_x_posts.py --from-wp

# 承認済みの投稿を実際にX投稿
python -X utf8 scripts/post_x_posts.py

# dry-run(投稿せずに確認のみ)
python -X utf8 scripts/post_x_posts.py --dry-run

B1〜B5 の投稿パターン:

パターン 名称 内容の方向
B1 体験入口型 「こんなことがあった」から始める
B2 学び直球型 「○○するには△△が大事」
B3 問いかけ型 読者に問いを投げる
B4 余韻型 感情・情景で終わる
B5 記事告知型 URL直球でブログへ誘導

Before/After:

指標 自動化前 自動化後
所要時間 15分/記事(投稿文を手動で考える) 3分/記事(生成→承認→投稿)

ハマった点: X API v2 の OAuth 2.0 PKCE 認証

X API には v1.1 と v2 があり、無料プランで使えるのは v2 のみです。認証方式も OAuth 1.0a(v1.1)から OAuth 2.0 PKCE(v2)に変わっていて、認証フローが異なります。

また、無料プランでは月1,500ツイートの上限があります。1日50ツイート・1記事5パターン×30記事とすると150ツイートになるため、実際には承認フィルターで上限管理しています。

# utils/x_client.py の投稿部分(概要)
import tweepy
client = tweepy.Client(
    consumer_key=CONSUMER_KEY,
    consumer_secret=CONSUMER_SECRET,
    access_token=ACCESS_TOKEN,
    access_token_secret=ACCESS_TOKEN_SECRET,
)
response = client.create_tweet(text=tweet_text)

この仕組みの詳しい実装方法は「ブログ記事からX投稿を自動生成する方法(準備中)」で解説予定です。

【4】ブログ全体の健全性チェック(blog_health_check.py)

スクリプト: blog_health_check.py

やっていること: WordPress REST API 経由で全記事を走査し、アイキャッチ未設定・カテゴリ未設定・タイトル空・本文が1,000字未満・重複slug など8項目の異常を一括検出する。公開記事・下書き・予約投稿など、すべてのステータスを対象にする。

Claude Code への指示文例:

blog_health_check.py を作って。

WordPress REST API で全記事を取得して、以下の異常を検出するスクリプト。

- アイキャッチ未設定(featured_media = 0)
- カテゴリ未設定
- タイトルが空または5文字未満
- 本文が1000字未満
- 最終更新から2年以上経過
- 重複slug
- noindex 設定あり(カスタムフィールドで確認)
- 90日以上更新されていない下書き

記事が100件を超えてもページネーションで全件取得するようにして。
異常は [WARN] / [INFO] のプレフィックスをつけてコンソール出力して。
.env に WP_BASE_URL / WP_USERNAME / WP_APP_PASSWORD を置く形で。

実行コマンド:

python -X utf8 scripts/blog_health_check.py

出力例:

[WARN] 記事 ID=345 「看護師1年目の転職」 アイキャッチ未設定
[WARN] 記事 ID=512 「男性看護師の働き方」 カテゴリ未設定
[INFO] 重複slug検出: nurse-career (ID: 201, 387)
チェック完了: 全187記事 / 異常 3件

チェック項目:

# チェック内容 基準
1 アイキャッチ画像 featured_media = 0 なら異常
2 カテゴリ設定 カテゴリが空なら異常
3 タイトル長 空または5文字未満なら異常
4 本文長 1,000字未満なら警告
5 最終更新日 2年以上更新なしなら情報
6 重複slug 同じslugが複数存在するなら異常
7 noindex確認 カスタムフィールドで確認できる範囲
8 古い下書き 90日以上更新されていない下書き

Before/After:

指標 自動化前 自動化後
確認方法 管理画面で目視(記事が増えると不可能) コマンド1発で全記事スキャン
所要時間 記事数×1分〜(100本なら100分以上) 2分(187記事)

ハマった点: 記事数が100件を超えたらページネーション処理が必要

WordPress REST API の per_page は最大100件です。記事が100件を超えると、page=1, 2, 3... とページを繰って全件取得する処理が必要になります。

# 全記事を取得するページネーション処理
page = 1
while True:
    r = requests.get(url, params={"per_page": 100, "page": page}, auth=auth(settings))
    if r.status_code == 400:  # ページが存在しない = 取得完了
        break
    posts.extend(r.json())
    page += 1

この処理を入れておかないと、100件目以降の記事の異常が検出されません。

【5】投稿直後の異常チェック(post_health_check.py)

スクリプト: post_health_check.py

やっていること: 記事を公開またはリライトした直後に、その1記事だけを対象に9項目の異常検査をする。HTTP 200確認・アイキャッチ・SEOメタ・JSON-LD・画像死活・内部リンク死活まで自動でチェックする。

Claude Code への指示文例:

post_health_check.py を作って。

投稿IDまたは記事URLを引数で受け取り、その1記事に対して
以下の9項目を検査して結果を出力するスクリプト。

1. 公開URLが HTTP 200 を返すか
2. アイキャッチが設定されているか
3. SEO Simple Pack の ssp_meta_title / ssp_meta_description が入っているか
4. JSON-LD(構造化データ)が出力されているか
5. カテゴリ・タグが付いているか
6. 記事内の img がすべて200を返すか
7. 同ドメインの内部リンクが200を返すか
8. 本文が1000字以上か
9. タイトル・slugが空でないか

--quiet オプションで異常があるときだけ非0終了する CI 向けモードも付けて。
.env に WP_BASE_URL / WP_USERNAME / WP_APP_PASSWORD を置く形で。

実行コマンド:

# 投稿IDで指定
python -X utf8 scripts/post_health_check.py --post-id 24

# URLで指定
python -X utf8 scripts/post_health_check.py --url https://halolab.jp/ai-blog-automation-howto/

# 異常があるときだけ非0終了(CI用途)
python -X utf8 scripts/post_health_check.py --post-id 24 --quiet

チェック項目:

# チェック内容
1 公開URLが HTTP 200 を返すか
2 アイキャッチが設定されているか
3 SEOメタ(ssp_meta_title / ssp_meta_description)が入っているか
4 JSON-LD(構造化データ)が出力されているか
5 カテゴリ・タグが付いているか
6 記事内画像がすべて200を返すか
7 同ドメインの内部リンクが200を返すか
8 本文文字数が1,000字以上か
9 タイトル・slugが空でないか

Before/After:

指標 自動化前 自動化後
確認方法 公開後にブラウザで目視 コマンド1発
所要時間 10分/記事 30秒/記事

ハマった点: SEO Simple Pack のメタが REST API では特殊な取得方法になる

SEO Simple Pack(SWELL 公式推奨の SEO プラグイン)のメタ情報は、WordPress の標準フィールドではなく、カスタムフィールドの ssp_meta_title / ssp_meta_description に格納されます。REST API 経由でこれを取得するには、_fields パラメータに meta を含め、さらに register_rest_field でカスタムフィールドをAPIに露出する設定が必要です。

Yoast SEO を使っている場合は yoast_head_json.title / yoast_head_json.description で取得できるため、.envWP_SEO_PLUGIN=seo-simple-pack または WP_SEO_PLUGIN=yoast で切り替えられるように実装しています。

【6】内部リンクの自動候補抽出(update_internal_links.py)

スクリプト: update_internal_links.py

やっていること: 対象記事の本文を走査し、他の公開記事タイトルと一致するプレーンテキストを検出して内部リンク候補を提案する。デフォルトは dry-run(候補表示のみ)で、--apply を付けると実際に <a> タグを挿入する。

Claude Code への指示文例:

update_internal_links.py を作って。

投稿IDを引数で受け取り、WordPress REST API でその記事の本文を取得。
他の全公開記事のタイトルと照合して、本文内に一致するプレーンテキストがあれば
内部リンク候補として表示する(dry-run)。

--apply を付けると実際に <a> タグを挿入して WordPress に更新。
すでに <a> タグ内にあるテキストは候補から除外して。
同じ記事へのリンクは1記事につき1箇所だけに制限して。
二重挿入を防ぐため、挿入済みマーカーを HTML コメントで埋め込んで。
--min-title-len オプションで短すぎるタイトルのマッチを除外できるようにして。

実行コマンド:

# 候補を表示するだけ(dry-run)
python -X utf8 scripts/update_internal_links.py --post-id 24

# 実際にリンクを挿入
python -X utf8 scripts/update_internal_links.py --post-id 24 --apply

# タイトル文字数の下限を指定(短すぎる記事名のマッチを除外)
python -X utf8 scripts/update_internal_links.py --post-id 24 --min-title-len 8

出力例(dry-run):

[候補] "看護師の転職" → <a href="https://ryman-nurse.com/nurse-job-change-timing/">看護師の転職</a>
  場所: 第3段落 7行目
[候補] "1年目の壁" → <a href="https://ryman-nurse.com/nurse-first-year-mental/">1年目の壁</a>
  場所: 第5段落 2行目
計2件の候補を検出しました。--apply を付けると挿入します。

Before/After:

指標 自動化前 自動化後
所要時間 15分/記事(どの記事にリンクを張るか手動で考える) 3分/記事(候補確認→適用)

ハマった点①: すでに <a> タグ内にあるテキストを除外するロジック

記事内に既存のリンクがある場合、そのリンクのテキスト部分も「マッチするプレーンテキスト」として誤検出されます。既存の <a> タグを除外する前処理が必要です。

# <a> タグ内のテキストをマッチ対象から除外
import re
body_no_anchor = re.sub(r'<a[^>]*>.*?</a>', '', body_html, flags=re.DOTALL)

ハマった点②: 冪等化マーカーで二重リンクを防ぐ

--apply を複数回実行すると同じリンクが二重に挿入されます。これを防ぐため、挿入後のHTMLに <!-- auto-internal-link:POST_ID --> マーカーを付け、次回以降は既にリンク済みの記事IDをスキップするようにしています。

【7】KWボリューム調査(research_keyword.py)

スクリプト: research_keyword.pygoogle-api/ 配下)

やっていること: Google Ads Keyword Planner API 経由で、指定キーワードの月間検索数・競合度・関連キーワード30件を取得する。SEO設計の入力データとして活用する。

Claude Code への指示文例:

research_keyword.py を作って。

CLI 引数でキーワードを1つ以上受け取り、
Google Ads Keyword Planner API(KeywordPlanIdeaService)で
月間検索数・競合度・関連キーワードを取得して表形式で表示する。

google-api/google-ads.yaml に developer_token / refresh_token /
login_customer_id を置く形で。
--json オプションで JSON 出力に切り替えられるようにして。
--limit オプションで関連キーワードの取得件数を指定できるようにして。
1リクエストで扱えるキーワードが20件上限なので、
それを超えた場合は自動でバッチ分割して全件取得して。

実行コマンド:

# 単一キーワードを調査
python google-api/research_keyword.py "看護師 転職"

# 複数キーワードをまとめて調査
python google-api/research_keyword.py "看護師 転職" "看護師 転職 40代" "看護師 年収"

# 関連キーワードを50件取得
python google-api/research_keyword.py --limit 50 "看護師 転職"

# JSON出力(プログラムから読む)
python google-api/research_keyword.py --json "看護師 転職"

出力例:

キーワード                月間検索数  競合度
---------------------------------------------
看護師 転職               22,200      高
看護師 転職 40代          1,600       中
看護師 年収               6,600       低

Before/After:

指標 自動化前 自動化後
所要時間 20分/テーマ(ラッコキーワード等のWebツール) 1分/テーマ
取得件数 1ツール = 数件〜数十件 関連30件を一括取得

ハマった点①: API Basic Access の申請〜承認に数日かかる

Google Ads Keyword Planner API を使うには、Google Ads アカウントと Keyword Planner API の Basic Access 申請が必要です。申請から承認まで2〜5営業日かかることが多いため、すぐには使えません。申請時に「プログラムで使う」旨を入力することが必要です。

ハマった点②: 1回20キーワード制限でバッチ分割が必要

API の1回のリクエストで扱えるキーワードは最大20件です。30件以上調べたい場合は、20件ずつに分割して複数回リクエストする処理が必要になります。--limit オプションで指定した件数に応じて自動的にバッチ分割するように実装しています。

この仕組みとSEO設計への活用方法については、「SEOタイトル・メタ自動生成(準備中)」で詳しく解説予定です。

【8】リライト効果測定(track_rewrite_effect.py)

スクリプト: track_rewrite_effect.py

やっていること: リライトまたは新規公開した記事を登録しておくと、Google Search Console のデータを使って「公開時点 → 1週後 → 1ヶ月後 → 3ヶ月後」のクリック数・表示回数・平均順位を自動で追跡し、効果サマリを出力する。

Claude Code への指示文例:

track_rewrite_effect.py を作って。

サブコマンド register / update / report の3モードで動くスクリプト。

register: slug / post-id / expected-clicks を受け取って
  baseline データ(公開時点の GSC 指標)を JSON に保存。

update: 登録済み記事を全件チェックして、
  「公開から1週後」「1ヶ月後」「3ヶ月後」のチェックポイントが
  到来していたら GSC データを取得して JSON に追記。

report: 全記事の効果サマリを出力(期待クリック数との差分も表示)。

GSC データは google-api/ の認証情報を使って取得。
記事ごとの JSON は blog-automation/reports/rewrite_tracking/{slug}.json に保存。

実行コマンド:

# 公開直後に登録(baseline 記録)
python -X utf8 scripts/track_rewrite_effect.py register \
    --slug nurse-first-year-mental \
    --post-id 2215 \
    --expected-clicks 30

# チェックポイントを手動で更新
python -X utf8 scripts/track_rewrite_effect.py update

# 効果サマリを出力
python -X utf8 scripts/track_rewrite_effect.py report

出力例(report コマンド):

=== リライト効果サマリ(2026-05-07)===

nurse-first-year-mental(登録: 2026-04-01)
  baseline : クリック 3 / 表示 120 / 順位 32.1
  +1週     : クリック 8 / 表示 310 / 順位 18.4
  +1ヶ月   : クリック 22 / 表示 890 / 順位 11.2
  期待リターン: 30クリック → 達成率 73%(+1ヶ月時点)

データは blog-automation/reports/rewrite_tracking/{slug}.json に蓄積されていきます。

Before/After:

指標 自動化前 自動化後
追跡方法 GSCを手動で開いてスプレッドシートに転記 登録1分 → 以降は自動追跡
所要時間 30分/記事×回数分 初回登録1分・その後は手動作業ゼロ

ハマった点: GSCデータは2〜3日遅延するため、公開直後の baseline は「データなし」が正常

Google Search Console のデータは、公開当日ではなく2〜3日後から取得できます。register コマンドを実行した当日は baseline が空になりますが、これは正常な動作です。数日後に update を実行することで自動的に baseline が埋まります。

この挙動を知らずに「データが取れていない、バグだ」と焦ると時間を無駄にします。GSCの遅延は仕様なので、--expected-clicks で目標値だけ設定して、あとは待てばOKです。

この仕組みの活用方法は「AIリライトの実践手順(準備中)」で詳しく解説予定です。

【9】毎日の巡回監視(patrol_collect.py)

スクリプト: patrol_collect.py / 連携: morning_brief.py

やっていること: 毎日朝5時に morning_brief.py から呼ばれて、ブログ全体の「構造系」「SEO系」「リンク系」のデータを収集し、JSON ファイルに保存する。保存した JSON を patrol-monitor subagent(Claude Code)が解釈して、緊急・警告・情報の3段階で要約レポートを出力する。

Claude Code への指示文例:

patrol_collect.py を作って。

WordPress REST API でブログ全記事を走査して、
以下のデータを JSON ファイルに保存するスクリプト。

収集対象:
- 構造系: アイキャッチ・カテゴリ・タイトル長・本文長・重複slug・古い下書き
- SEO系: noindex 検出・サイトマップ応答・robots.txt 応答
- リンク系: 記事内の内部リンク切れ・画像404
- 全公開記事のメタ snapshot

出力先: blog-automation/reports/patrol_YYYY-MM-DD-raw.json
Windows 環境で日本語が文字化けしないよう UTF-8 を強制して。
morning_brief.py から呼ばれることを想定した設計にして。

実行コマンド:

# 単独実行(手動で巡回データを収集)
python -X utf8 scripts/patrol_collect.py

# morning_brief から自動実行される(毎朝5時)
python -X utf8 scripts/morning_brief.py

収集するデータ:

{
  "date": "2026-05-07",
  "structural_issues": [
    {"id": 345, "title": "看護師1年目の転職", "issue": "no_eyecatch"},
    ...
  ],
  "seo": {
    "sitemap_ok": true,
    "robots_ok": true
  },
  "broken_links": [],
  "broken_images": [],
  "posts_snapshot": [...]
}

patrol-monitor subagent がこの JSON を読んで、次のような形式で要約します:

🔴 緊急(今日中に対応)
  - なし

🟡 警告(今週中に対応)
  - 記事ID 345「看護師1年目の転職」アイキャッチ未設定(3日継続)

🟢 情報
  - sitemap.xml: 正常
  - 先週から新規記事3本インデックス済み

Before/After:

指標 自動化前 自動化後
問題の発見 読者から指摘されてから気づく(受動的) 毎朝自動で異常検知(能動的)
所要時間 不定(気づくまで放置) 人手ゼロ

ハマった点: Windows環境でのJSONエンコーディング

Windows 環境でスクリプトを実行すると、JSON の日本語テキストが文字化けすることがあります。解決策は2つです。

  1. python -X utf8 オプションで実行する
  2. スクリプト冒頭に os.environ.setdefault("PYTHONUTF8", "1") を入れる
# patrol_collect.py 冒頭(エンコーディング強制)
os.environ.setdefault("PYTHONUTF8", "1")
if hasattr(sys.stdout, "reconfigure"):
    sys.stdout.reconfigure(encoding="utf-8", errors="replace")

また JSON ファイルへの書き込み時も ensure_ascii=False を指定しないと、日本語が 第三段落... のようにエスケープされて可読性がゼロになります。

【10】セッションログの自動チェック(auto_log.py)

スクリプト: auto_log.py

やっていること: Claude Code のセッション終了時に自動実行される Stop hook として動作する。当日ファイルを編集したプロジェクト(ai-blog-automation-lab / ryman-nurse.com)に対して、当日の作業ログが更新されているかを確認し、更新されていない場合は exit code 2 で Claude に警告を返す。

Claude Code への指示文例:

auto_log.py を作って。

Claude Code の Stop hook として動作するスクリプト。

ai-blog-automation-lab / ryman-nurse 配下を走査して、
「今日(JST)mtime が当日のファイルが存在する」のに
「そのプロジェクトの今日の作業ログが更新されていない」場合は
stderr に警告メッセージを出して exit code 2 で終了する。

正常終了(ログ更新済み)は exit code 0 で何も出さない。
Stop hook は exit code 2 を返すと Claude が次の応答前に
stderr を読む仕様なので、それを使ってログ追記を促す設計で。
今日のログファイルが存在しない場合はテンプレートを作成してから
exit code 2 を返す。

設定方法.claude/settings.json に追記):

{
  "hooks": {
    "Stop": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "python blog-automation/scripts/auto_log.py"
          }
        ]
      }
    ]
  }
}

Before/After:

指標 自動化前 自動化後
ログ追記の状況 忘れる(2回指摘を受けた) セッション終了時に毎回警告

ハマった点: Stop hook の仕様理解(exit code 2 の意味)

Claude Code の Stop hook は、コマンドが exit code 2 を返すと「警告あり」として Claude が次の応答前に標準エラー出力を読みます。この仕組みを使うことで、「ログが未更新のまま終了しようとするとClaude がストップして注意喚起する」動作が実現できます。

exit code 0 は「正常終了・何もしない」、exit code 2 は「警告・stderrを読む」、それ以外は「エラー」という仕様です。

# auto_log.py の警告出力部分
if missing_log_projects:
    print(
        f"\n⚠️  以下のプロジェクトで作業ログが未更新です:\n" +
        "\n".join(f"  - {p}" for p in missing_log_projects),
        file=sys.stderr
    )
    sys.exit(2)

私はログ追記を2回忘れてハロさんから指摘を受けました。この hook を入れてからは、ログを書かずにセッションを終わらせることがなくなりました。「自分の作業習慣をコードで矯正する」という、ちょっと変わった使い方です。

10個を組み合わせて月25本ペースを実現している話

10個のスクリプトをバラバラに使っているのではなく、一連の「自動完走モード」として連鎖させています。

具体的には、体験素材シートが完成した記事フォルダを指定すると、以下が順番に動きます。

SEO設計(競合分析 → 構成案)
  ↓
記事ライター(draft 作成)
  ↓
品質審査(合格まで差し戻し)
  ↓
[2] generate_eyecatch.py(アイキャッチ生成)
  ↓
[1] publish_post.py(WordPress 投稿)
  ↓
[3] generate_x_posts.py + post_x_posts.py(X 投稿生成・予約)
  ↓
[5] post_health_check.py(投稿直後の異常チェック)
  ↓
[8] track_rewrite_effect.py(効果追跡 baseline 登録)

これと並行して、毎日朝5時に [9] patrol_collect.py + morning_brief.py が動いてサイトの異常を検知し、月次で [4] blog_health_check.py が全記事の健全性を一括確認します。新しいクラスター記事を公開した後には [6] update_internal_links.py が既存記事に自動で内部リンクを追加し、SEO設計に入る前には [7] research_keyword.py がKWボリュームを即座に取得します。そして [10] auto_log.py が毎日の作業ログ追記を担保します。

この連鎖によって、1本の記事が完成してから公開・告知・追跡・異常検知まで、人間がやるのは「体験インタビューに答えること」と「品質審査後の最終確認」だけになっています。

費用の目安:

ツール 費用
Claude Max 20x プラン 約30,000円/月
OpenAI API(gpt-image-2・月8本) 200〜300円/月
X API(無料プラン) 0円
Google Ads API(Basic Access) 0円
GSC API 0円

30,000円という数字は大きく見えますが、これは私がすでに月25本ペースで記事制作まで回していることを前提にした、最大プランの費用です。最初は Claude Pro(月3,000円)から始めれば十分です。スクリプトの作成・テストは Pro プランでも問題なくできます。私自身、Pro → Max 5x → Max 20x と段階的に上げてきました。

非エンジニアがここまで到達できた理由を一言で言うと、「Claude Code に指示する人間でいられたから」だと思っています。スクリプトの中身は書けなくても、「こんな動作をするスクリプトが欲しい」という言語化はできます。その言語化の力があれば、コードは Claude Code が書いてくれます。

まとめ — 自動化は「全部やるか、やらないか」ではない

10個のスクリプトを紹介しましたが、最初から全部を揃える必要はありません。

1つずつ試して、効果が大きかったものから定着させていけばいいと思っています。

まず1つだけ始めるなら、publish_post.py(WordPress自動投稿)をおすすめします。毎回30分かかっていた作業が1分になる効果が一番わかりやすく、下書き投稿から始めれば間違って公開してしまうリスクもありません。次に generate_eyecatch.py(アイキャッチ生成)で画像作成の時間を削り、generate_x_posts.py + post_x_posts.py(X投稿自動化)で告知の手間を減らす、という順番が現実的です。

保守系の4つ(blog_health_check.py / post_health_check.py / patrol_collect.py / track_rewrite_effect.py)は、記事数が増えてきてから入れるのが効果的です。記事が10本以下の時点では、手動確認でも追いきれます。

各スクリプトを Claude Code に作らせるときの指示文は、この記事の各項目で紹介したサンプルがそのまま使えます。「スクリプト名と何をしたいか」を伝えるだけで、コードは生成されます。「コードが書けないから自動化できない」ということにはなりません。試してみたいものがあれば、まずは一番シンプルな1本から始めてみてください。

よくある質問

Q1. プログラミングができなくてもスクリプトは作れますか?

Claude Code はターミナルで自然言語の指示を入力するだけで Python スクリプトを生成してくれるツールです。コードを自分で書く必要はありません。

私は看護師で、プログラミング経験はゼロの状態からスクリプト30個超を作りました。「やりたいこと」を具体的に言語化できれば、コードは Claude Code が書いてくれます。たとえば「WordPress REST API に Markdown を投稿するスクリプトを作って。frontmatter から title・categories・tags を読み取って、Markdown を HTML に変換してから投稿する処理を含めて」という指示で、1分以内に動くコードが生成されます。必要なのはプログラミングの知識ではなく、「何をしたいか」を言葉にする力です。

Q2. 10個の自動化をすべて揃えるのにいくらかかりますか?

Claude Code は月3,000円の Pro プランから始められます。OpenAI API(アイキャッチ生成)は月200〜300円、X API と Google API は無料枠で動きます。最初の投資は月3,000円程度です。

私は Pro → Max 5x(月10,000円)→ Max 20x(約30,000円)と段階的に上げました。最初は Pro で十分で、記事数が増えてコンテキストが長くなったり、複数のスクリプトを並行して動かすことが増えてから上位プランに切り替えればいいと思っています。

Q3. まず1つだけ始めるなら何がおすすめですか?

publish_post.py(WordPress自動投稿)が最初の1つとして最適です。

最も時間削減効果が大きく(30分 → 1分)、失敗してもリスクが低い(デフォルトが下書き投稿なので公開されない)、かつ他のスクリプトと連携して使えるためです。frontmatter を整えてコマンドを1発打つだけで投稿が完了する体験は、「自動化って実際に動くんだ」という実感を得やすくします。その実感があると、次のスクリプトを作るモチベーションにつながります。

さいごに

30個超のスクリプト一覧と、それぞれの用途・ハマりポイント・Claude Code への指示文サンプルは、note にまとめています。

コードを全文公開しているので、そのまま使うこともできます。興味があれば覗いてみてください。

ここで紹介した10個の自動化スクリプトのコード詳細は、note の有料記事で公開しています(500円)。

note:WordPress自動投稿【コード公開】

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

目次