WordPress REST APIで記事投稿を爆速化:ブラウザ自動化から解放
はじめに
ブログ記事の自動投稿をブラウザ自動化(Selenium/Playwright)で実装していませんか?この記事では、WordPress REST APIを使って記事投稿を50-75分→10秒に短縮した実装を紹介します。
ブラウザ自動化の限界
Seleniumでの投稿フロー
従来のブラウザ自動化:
from selenium import webdriver
def post_with_selenium(title, content, category):
driver = webdriver.Chrome()
# 1. ログイン(10-15秒)
driver.get("https://example.com/wp-admin")
driver.find_element_by_name("log").send_keys(username)
driver.find_element_by_name("pwd").send_keys(password)
driver.find_element_by_id("wp-submit").click()
time.sleep(5)
# 2. 新規投稿ページ(5-10秒)
driver.get("https://example.com/wp-admin/post-new.php")
time.sleep(3)
# 3. タイトル入力
driver.find_element_by_id("title").send_keys(title)
# 4. 本文入力(Block Editorは複雑)
# ...複雑なセレクタ操作...
# 5. カテゴリ選択
# ...ドロップダウン操作...
# 6. 公開ボタン(5秒)
driver.find_element_by_class("editor-post-publish-button").click()
time.sleep(5)
driver.quit()
問題点:
– 1記事 = 約7-10分(ブラウザ起動・画面遷移の待ち時間)
– 6記事投稿 = 50-75分
– UI変更でスクリプト破損リスク
– ヘッドレスブラウザでもメモリ消費大
解決策:WordPress REST API
API認証
Application Passwordを使います(WordPress 5.6+)。
import requests
from requests.auth import HTTPBasicAuth
WORDPRESS_URL = "https://obaba-win.com"
USERNAME = "obaba"
APP_PASSWORD = "75OJjbLkwgml8VE0TJZ3sJA1" # Application Password
def get_auth():
return HTTPBasicAuth(USERNAME, APP_PASSWORD)
記事投稿
シンプルなHTTP POSTで投稿できます。
def post_article_via_api(title, content, category_id, status='publish'):
"""
WordPress REST APIで記事投稿
Args:
title: 記事タイトル
content: 記事本文(HTML可)
category_id: カテゴリID
status: 'publish' / 'draft'
Returns:
投稿ID、URL
"""
endpoint = f"{WORDPRESS_URL}/wp-json/wp/v2/posts"
data = {
"title": title,
"content": content,
"categories": [category_id],
"status": status
}
response = requests.post(
endpoint,
json=data,
auth=get_auth()
)
if response.status_code == 201:
post_data = response.json()
return post_data['id'], post_data['link']
else:
raise Exception(f"投稿失敗: {response.status_code} - {response.text}")
カテゴリ取得
カテゴリIDはAPIで取得します。
def get_categories():
"""
WordPressのカテゴリ一覧を取得
"""
endpoint = f"{WORDPRESS_URL}/wp-json/wp/v2/categories"
response = requests.get(endpoint, auth=get_auth())
if response.status_code == 200:
categories = response.json()
return {cat['name']: cat['id'] for cat in categories}
else:
raise Exception("カテゴリ取得失敗")
# 使用例
categories = get_categories()
# {'AI・LLM': 176, 'Python': 12, 'JavaScript': 13, ...}
バッチ投稿の実装
複数記事を一括投稿
def batch_post_articles(articles):
"""
複数記事を連続投稿
Args:
articles: [{'title': ..., 'content': ..., 'category': ...}, ...]
Returns:
投稿結果のリスト
"""
categories = get_categories()
results = []
for i, article in enumerate(articles, 1):
try:
category_id = categories.get(article['category'])
if not category_id:
print(f"⚠️ カテゴリ不明: {article['category']}")
continue
post_id, url = post_article_via_api(
title=article['title'],
content=article['content'],
category_id=category_id,
status='publish'
)
results.append({
'title': article['title'],
'post_id': post_id,
'url': url,
'status': 'success'
})
print(f"✅ [{i}/{len(articles)}] 投稿完了: {article['title']}")
except Exception as e:
results.append({
'title': article['title'],
'status': 'failed',
'error': str(e)
})
print(f"❌ [{i}/{len(articles)}] 投稿失敗: {article['title']} - {e}")
return results
Markdownから自動変換
Markdown記事をHTMLに変換して投稿します。
import markdown
def post_markdown_article(md_file, category):
"""
Markdownファイルを読み込んでWordPressに投稿
"""
with open(md_file, 'r', encoding='utf-8') as f:
md_content = f.read()
# タイトル抽出(最初の# 見出し)
lines = md_content.split('\n')
title = lines[0].lstrip('#').strip()
body = '\n'.join(lines[1:]).strip()
# Markdown → HTML変換
html_content = markdown.markdown(
body,
extensions=['fenced_code', 'tables', 'codehilite']
)
# 投稿
categories = get_categories()
category_id = categories[category]
post_id, url = post_article_via_api(title, html_content, category_id)
print(f"✅ 投稿完了: {title}")
print(f" URL: {url}")
return post_id, url
実運用での改善
カテゴリ必須チェック
uncategorized投稿を防ぎます。
def post_article_safe(title, content, category_name):
"""
カテゴリ必須チェック付き投稿
"""
categories = get_categories()
if category_name not in categories:
raise ValueError(f"カテゴリ不明: {category_name}")
if category_name == "uncategorized":
raise ValueError("uncategorized への投稿は禁止")
category_id = categories[category_name]
return post_article_via_api(title, content, category_id)
エラーハンドリング
API制限やネットワークエラーに対応します。
import time
def post_with_retry(title, content, category_id, max_retries=3):
"""
リトライ付き投稿
"""
for attempt in range(1, max_retries + 1):
try:
return post_article_via_api(title, content, category_id)
except Exception as e:
if attempt == max_retries:
raise
print(f"⚠️ 投稿失敗(試行{attempt}/{max_retries}): {e}")
time.sleep(2 ** attempt) # 指数バックオフ
パフォーマンス比較
ブラウザ自動化 vs REST API
| 項目 | Selenium | REST API |
|---|---|---|
| 1記事投稿 | 7-10分 | 1-2秒 |
| 6記事バッチ | 50-75分 | 10秒 |
| メモリ消費 | 500MB+ | 10MB以下 |
| UI変更の影響 | 破損リスク大 | 影響なし |
実績
2026-03-26に6記事を一括投稿:
$ time python3 wp_auto_post_v2.py
✅ [1/6] 投稿完了: WordPress自動投稿を爆速化...
✅ [2/6] 投稿完了: スマート提案機能の実装...
✅ [3/6] 投稿完了: Google Tasks統合でタスク管理を進化...
✅ [4/6] 投稿完了: ファクトチェックをAIで自動化...
✅ [5/6] 投稿完了: Next.js 15移行ガイド...
✅ [6/6] 投稿完了: フォルダ構造ベストプラクティス...
real 0m9.847s
user 0m1.234s
sys 0m0.089s
約10秒で6記事投稿完了。従来の50-75分から99%削減。
セキュリティ
Application Passwordの管理
環境変数で管理します。
# .env
WORDPRESS_URL=https://obaba-win.com
WORDPRESS_USER=obaba
WORDPRESS_APP_PASSWORD=75OJjbLkwgml8VE0TJZ3sJA1
from dotenv import load_dotenv
import os
load_dotenv()
WORDPRESS_URL = os.getenv('WORDPRESS_URL')
USERNAME = os.getenv('WORDPRESS_USER')
APP_PASSWORD = os.getenv('WORDPRESS_APP_PASSWORD')
パスワード再生成
Application Passwordは再生成可能です。
- WordPress管理画面 → ユーザー → プロフィール
- “Application Passwords” セクション
- 古いパスワードを削除、新規生成
まとめ
WordPress REST APIを使うことで、記事投稿を劇的に高速化できます。ブラウザ自動化の50-75分が10秒になり、メモリ消費も大幅に削減。バッチ投稿やMarkdown変換と組み合わせることで、完全自動化されたブログ運用が実現できます。
関連記事:
– AI駆動タスク自動振り分け
– OpenClaw Cronジョブ活用術
– Downloads整理・次世代版構想