この記事に広告リンクはありません。
「Claude Codeでブログ作業を自動化した話」の続きです。前回は全体の流れを書きました。今回は、その中心にある「PythonでWordPressに記事を入れる部分」を、手を動かせる形でまとめます。
前回の記事はこちら:Claude Codeでブログ作業を自動化|初心者がWordPressの下書き投稿まで仕組み化した手順
WordPressへの入稿も、一人で回していると地味に時間を取られる「事務」です。手作業を1つ減らすつもりで読んでみてください。
最初に書いておくと、この記事のやり方は「下書き」で入れるところまでです。いきなり公開する仕組みは作りません。理由は後半で書きます。
PythonでWordPressに投稿すると何ができる?
WordPressには、外のプログラムから記事を出し入れできる入口(REST API:レスト・エーピーアイ)が最初から付いています。Pythonからそこに記事を送ると、管理画面を開かずに記事が入ります。
私が実際に使っているのは、次のような作業です。
| できること | 私の使い方 |
|---|---|
| 記事を下書きで保存 | 毎回これ。公開は人が管理画面で確認してから |
| カテゴリー・タグの指定 | 名前で指定(数字で指定して失敗した話は後で) |
| アイキャッチ画像の登録 | 画像をアップロードして記事に設定 |
| SEOタイトル・説明文の設定 | SEOプラグインの欄にも入れる |
| 予約投稿 | 日時を指定して予約(登山ブログで使用) |
逆に、記事の中身が正しいか、公開していいかの判断はできません。 そこは人の仕事です。
準備するもの
| 準備するもの | 説明 |
|---|---|
| WordPressのブログ | URLが https:// で始まっていること |
| Python | 無料。私はAIに手順を聞きながらインストールしました |
| requests(リクエスツ) | PythonからWebに送るための追加部品。無料 |
| アプリケーションパスワード | プログラム専用の合言葉。WordPressの標準機能 |
Pythonを入れたら、requestsを追加します。Windowsなら「コマンドプロンプト」を開いて、次の1行を打ちます。
python -m pip install requests
ちなみに私のプログラムは、ゆる登山のときも、このブログのときも、Claudeに作ってもらいました。中身を全部理解しているわけではありませんが、何をするプログラムなのかは毎回説明してもらっています。
手順1:アプリケーションパスワードを発行する
ふだんWordPressにログインするパスワードとは別物です。プログラム専用のパスワードを、WordPressに発行してもらいます。
- WordPressの管理画面で「ユーザー」→「プロフィール」を開く
- 下のほうの「アプリケーションパスワード」を探す
- 名前の欄に「python投稿用」など分かる名前を入れて、「新しいアプリケーションパスワードを追加」を押す
- 表示された文字列をメモする(この画面を閉じると二度と表示されません)

ふだんのログインパスワードを使わない理由は、もし漏れたときに「このパスワードだけ無効にする」ができるからです。
手順2:パスワードをコードに書かず、別のファイルに分ける
プログラムの中にパスワードを直接書くのはやめましょう。プログラムを人に見せたり、AIに渡したりしたときに一緒に漏れるからです。
プログラムと同じフォルダに「.env」という名前のファイルを作り、次の3行を書きます。
WP_URL=https://あなたのブログのURL
WP_USER=WordPressのユーザー名
WP_APP_PASSWORD=手順1で発行したパスワード
私は、このファイルの中身だけは自分で書き込んでいます。AIに「パスワードを貼って」と言われても貼りません。AIには「.envを使って」とだけ伝えます。
手順3:接続できるか確認する(何も変更しない)
いきなり記事を入れず、まずは「つながるか」だけを確認します。
下のサンプルを「wp_draft_sample.py」という名前で、.envと同じフォルダに保存してください。
"""WordPressに記事を「下書き」で1本入れるサンプル。
使い方:
python wp_draft_sample.py check # 接続確認だけ(何も変更しない)
python wp_draft_sample.py post # 下書きを1本作る
"""
import sys
from pathlib import Path
import requests
def load_env(path=".env"):
env = {}
for line in Path(path).read_text(encoding="utf-8").splitlines():
if "=" in line and not line.strip().startswith("#"):
key, value = line.split("=", 1)
env[key.strip()] = value.strip()
return env
ENV = load_env()
API = ENV["WP_URL"].rstrip("/") + "/wp-json/wp/v2/"
AUTH = (ENV["WP_USER"], ENV["WP_APP_PASSWORD"])
def category_id(name):
"""カテゴリーを「名前」で探してIDを返す(数字を直接渡さない)"""
for cat in requests.get(API + "categories", params={"search": name}, timeout=30).json():
if cat["name"] == name:
return cat["id"]
sys.exit(f"カテゴリー「{name}」が見つかりません。先に管理画面で作ってください")
if sys.argv[1:] == ["check"]:
r = requests.get(API + "users/me", auth=AUTH, timeout=30)
print(r.status_code, "接続OK" if r.ok else r.text[:200])
elif sys.argv[1:] == ["post"]:
data = {
"title": "テスト投稿(あとで消す)",
"content": "<p>Pythonから下書きで入れました。</p>",
"status": "draft", # ここが draft なら公開されない
"categories": [category_id("ブログ・発信の自動化")],
}
r = requests.post(API + "posts", auth=AUTH, json=data, timeout=30)
if r.ok:
post = r.json()
print("下書きを作成しました:ID", post["id"], "状態", post["status"])
else:
print("失敗:", r.status_code, r.text[:200])
else:
print(__doc__)
保存したフォルダでコマンドプロンプトを開き、こう打ちます。
python wp_draft_sample.py check
「200 接続OK」と出れば成功です。この確認は、記事を読むだけで何も変更しません。
※ このサンプルは、2026年11月10日にこのブログで実際に動かして確認しました。
手順4:下書きを1本入れる
接続できたら、いよいよ下書きを入れます。サンプルの「ブログ・発信の自動化」の部分は、あなたのブログにあるカテゴリー名に書き換えてください。
python wp_draft_sample.py post
「下書きを作成しました:ID ○○ 状態 draft」と出たら、管理画面の「投稿」→「下書き」を見てください。「テスト投稿(あとで消す)」が入っているはずです。確認したら、その下書きは消してOKです。
ポイントは "status": "draft" の1行です。ここが draft である限り、記事は公開されません。
手順5:本文・アイキャッチ・SEO欄も入れる
慣れてきたら、少しずつ機能を足していきます。私の場合はこの順番でした。
- 本文をファイルから読む:記事をテキストファイル(Markdown)で書き、Pythonで読み込んでHTMLに変換して送る
- タグ:カテゴリーと同じく、名前で探してIDに変える
- アイキャッチ画像:画像をアップロードして、返ってきたIDを記事の「featured_media」に入れる
- SEOタイトル・説明文:SEOプラグインの欄に入れる(私はAll in One SEOを使用)
ここは、自分で書くよりAIに「このサンプルに○○を足して」と頼むほうが早いです。ただし、次の章の失敗を先に読んでおくと、遠回りが減ると思います。
実際にハマった5つのこと
全部、私の登山ブログとこのブログの運用で実際に起きたことです。
1.カテゴリーを数字で渡したら「18」というカテゴリーができていた
カテゴリーは本来、番号(ID)で指定します。ところが私のプログラムは「名前」を受け取って、見つからなければ新しく作る作りでした。そこに数字を渡したせいで、「18」「4」といった名前のカテゴリーが次々に作られていました。
気づいたのは、記事をまとめて点検したときです。13本の記事が、意味のない数字のカテゴリーに入っていました。 公開されると「/category/18/」のような、誰も得しないページができてしまいます。
対策:カテゴリーは名前で指定し、プログラムの中で名前→番号に変える。投稿したあと、カテゴリーが意図どおりか確認する。
2.SEOタイトルだけ送ったら、説明文が消えた
All in One SEO(SEOプラグイン)は、SEOタイトルと説明文を片方だけ送ると、もう片方が初期値に戻ってしまうことがありました。
さらに、このプラグインに送るときの記事番号の書き方が、読み出すときと送るときで違っていました。公式の説明には見当たらず、何パターンか試して分かりました。
対策:SEOタイトルと説明文は、必ずセットで送る。送ったあとに読み出して、両方入っているか確認する。
3.サーバーのセキュリティに止められた(403)
レンタルサーバーには、怪しい通信を止める仕組み(WAF:ワフ)が入っていることがあります。私の環境では、プログラムからの画像のアップロードや削除が、「閲覧できません」という画面で止められたことがありました。
WordPressの設定やパスワードの問題ではないので、ここで悩みました。私の環境では、
- 画像の送り方(データの形式)を変える
- 削除の送り方を変える
- 画像をJPEGに変えて送り直す
といった方法で通るようになりました。ただ、何が止められるかはサーバーや設定によって違うので、「これをすれば必ず通る」とは言えません。
対策:403が出たら、返ってきた画面の中身を見る。「閲覧できません」ならサーバー側のセキュリティを疑う。
4.Windowsで「python3」と打ったら動かなかった
ネットの説明には python3 と書いてあることが多いのですが、私のWindowsでは、Microsoft Storeの入口のようなものが反応して、ちゃんと動きませんでした。
対策:Windowsでは python と打つ。
5.記事内のリンクを「?p=123」で書いたらSearch Consoleで注意された
記事の中で別の記事にリンクするとき、記事番号を使った「?p=123」の形で書いていました。これでも開けるのですが、正式なURLへ転送(リダイレクト)される形になるため、Search Consoleで「リダイレクトがあります」と出ていました。
対策:記事内のリンクは「/記事のスラッグ/」の正式なURLで書く。私はすでにあった記事のリンクを全部書き直しました。
安全のために付けている仕組み
今使っているプログラムには、Claudeと相談して次の安全装置を付けています。
- 下書きしか作らない:公開は別の操作で、私がOKしたときだけ
- 公開済みの記事は上書きしない:同じURLの記事が公開済みなら止まる
- 接続先を確認する:違うブログにつながっていたら止まる(登山ブログを間違って触らないため)
- 仮置き文字が残っていたら公開しない:「ここに画像を入れる」のような書きかけの目印を探す
- 記録を残す:いつ・何を・どうしたかをファイルに書き出す
最初から全部はいりません。まずは「下書きしか作らない」だけで十分です。
よくあるエラーと確認ポイント
| 出た番号 | よくある原因 | 確認すること |
|---|---|---|
| 401 | ユーザー名かアプリケーションパスワードが違う | .envの値。ふだんのログインパスワードを入れていないか |
| 403 | 権限が足りない/サーバーのセキュリティに止められた | 返ってきた画面の中身 |
| 404 | URLが違う | .envのURL。パーマリンク設定 |
401は、私もこのブログを立ち上げた日に出しました。.envに入れた値が、アプリケーションパスワードではなかったのが原因でした。正しい値に入れ替えたら、すぐにつながりました。
まとめ|まずは「下書きで1本入れる」から
PythonでWordPressに投稿する仕組みは、思っていたより短いコードで動きます。
いきなり全部を自動にせず、
- 接続確認
- 下書きを1本
- カテゴリーやアイキャッチを足す
と、1つずつ進めるのがおすすめです。そして、公開ボタンは自分で押す。ここだけは手放さないほうがいいと思っています。
全体の流れやClaude Codeとの組み合わせ方は、前回の記事に書いています。
Claude Codeでブログ作業を自動化|初心者がWordPressの下書き投稿まで仕組み化した手順
