WordPressへの自動差し込み:サムネイルの最適化方法

WordPressへの自動差し込み:サムネイルの最適化方法 — WordPress, 自動化, サムネイル AIテキスト

前回の記事では、AIを使ったアイキャッチ画像の自動生成を試しました。記事内容からプロンプトを生成し、Stable Diffusionで画像を作成するところまでは自動化できています。

しかし、生成した画像をWordPressの記事に設定する作業は、まだ手動のままです。画像をアップロードしてアイキャッチに設定する工程は単純ですが、記事数が増えると意外に手間がかかります。

そこで今回は、WordPressのREST APIを使って、生成したサムネイルを記事に自動設定する仕組みを試してみます。記事生成からサムネイル設定までを一連のワークフローとして自動化することが目的です。

自作ツールの選択とREST APIによる自動化

この課題を解決するため、WordPress REST APIを活用した自動化プロセスを構築します。

前提として、WordPressにはアイキャッチ画像を生成する機能がいくつかあります。

既存プラグインとの比較

WordPressには、アイキャッチ画像を自動設定するためのプラグインもいくつか存在します。(2026年1月現在)

例えば、記事内の画像を自動的にアイキャッチに設定するものや、タイトルから画像を生成するものなどです。

ただし、これらの多くは「既存画像を使う」か「テンプレート画像を生成する」仕組みに限られます。AIで生成した画像を外部ツールから差し込み、記事更新に合わせて自動的に最適化するような用途には対応していません。

そのため今回は、WordPressのREST APIを使い、サムネイル生成から記事への設定までを自作スクリプトで自動化する方法を採用します。

方法カスタマイズ性コスト自動更新用途
Auto Featured Image (Auto Post Thumbnail)無料投稿時のみ記事内の最初の画像をアイキャッチに設定
Smart Auto Featured Image無料 / 有料投稿時タイトルやカテゴリからテンプレート画像を生成
Auto Featured Image from Title低〜中無料投稿時タイトル文字を使ったアイキャッチ生成
自作ツール(REST API)非常に高無料任意AI生成画像や外部ツールと連携可能

技術的実装手順

記事を一つ一つ指定する方法もありますが、せっかくの自動化なのでもうひと手間加えます。

WordPress REST APIを使えば、ドラフト記事の一覧を取得し、featured_media が 0 の投稿だけを抽出することで、アイキャッチ未設定の記事を機械的に判定できます。

コード例は下記のようになります。

import os
import requests
from requests.auth import HTTPBasicAuth


WP_BASE_URL = os.getenv("WP_BASE_URL", "https://pareido.jp")
WP_USERNAME = os.getenv("WP_USERNAME", "YOUR_USERNAME")
WP_APP_PASSWORD = os.getenv("WP_APP_PASSWORD", "YOUR_APPLICATION_PASSWORD")


def fetch_draft_posts_without_featured_image(
    base_url: str,
    username: str,
    app_password: str,
) -> list[dict]:
    session = requests.Session()
    session.auth = HTTPBasicAuth(username, app_password)

    endpoint = f"{base_url.rstrip('/')}/wp-json/wp/v2/posts"
    page = 1
    results: list[dict] = []

    while True:
        params = {
            "status": "draft",
            "per_page": 100,
            "page": page,
            "_fields": "id,date,title,featured_media,link",
        }

        response = session.get(endpoint, params=params, timeout=30)
        response.raise_for_status()

        posts = response.json()
        if not posts:
            break

        for post in posts:
            if post.get("featured_media", 0) == 0:
                results.append(
                    {
                        "id": post["id"],
                        "date": post.get("date"),
                        "title": post.get("title", {}).get("rendered", ""),
                        "link": post.get("link", ""),
                    }
                )

        total_pages = int(response.headers.get("X-WP-TotalPages", "1"))
        if page >= total_pages:
            break

        page += 1

    return results


if __name__ == "__main__":
    drafts = fetch_draft_posts_without_featured_image(
        base_url=WP_BASE_URL,
        username=WP_USERNAME,
        app_password=WP_APP_PASSWORD,
    )

    if not drafts:
        print("アイキャッチ未設定のドラフト記事はありません。")
    else:
        print(f"アイキャッチ未設定のドラフト記事: {len(drafts)}件")
        for post in drafts:
            print(f"[{post['id']}] {post['title']} ({post['date']})")
            print(f"  {post['link']}")

次に、対象となる記事の本文を取得します。

WordPress REST APIで取得できる本文(content)は、プレーンテキストではなくHTML形式で返されます。そのためLLMによる解析やキーワード抽出に利用する場合は、必要に応じてHTMLタグを除去してから処理する方が安全です。

特に <code><pre> などのコードブロックが含まれる記事では、タグ付きのまま処理してLLMに渡すとノイズになることがあります。

def fetch_post_content(
    base_url: str,
    username: str,
    app_password: str,
    post_id: int,
) -> dict:

    session = requests.Session()
    session.auth = HTTPBasicAuth(username, app_password)

    endpoint = f"{base_url.rstrip('/')}/wp-json/wp/v2/posts/{post_id}"

    params = {
        "_fields": "id,title,content,excerpt"
    }

    response = session.get(endpoint, params=params, timeout=30)
    response.raise_for_status()

    post = response.json()

    return {
        "id": post["id"],
        "title": post.get("title", {}).get("rendered", ""),
        "content": post.get("content", {}).get("rendered", ""),
        "excerpt": post.get("excerpt", {}).get("rendered", ""),
    }


if __name__ == "__main__":

    drafts = fetch_draft_posts_without_featured_image(
        base_url=WP_BASE_URL,
        username=WP_USERNAME,
        app_password=WP_APP_PASSWORD,
    )

    for post in drafts:
        data = fetch_post_content(
            base_url=WP_BASE_URL,
            username=WP_USERNAME,
            app_password=WP_APP_PASSWORD,
            post_id=post["id"],
        )

        print("----")
        print(data["title"])
        print(data["content"][:200])

取得した記事内容から、前回の内容に沿ってpng形式でサムネイルを生成します。

WordPress REST APIでは、サムネイルを記事の「アイキャッチ画像」として設定します。
アップロードには 2段階の処理が必要で、これは手作業でアイキャッチ画像を設定する手順と同様です。

  1. /media に画像をアップロードして media_id を取得し、
  2. /posts/{id}featured_media にそのIDを設定する

コード例は下記のようになります。

def upload_media(
    base_url: str,
    username: str,
    app_password: str,
    image_path: str,
) -> int:

    session = requests.Session()
    session.auth = HTTPBasicAuth(username, app_password)

    endpoint = f"{base_url.rstrip('/')}/wp-json/wp/v2/media"

    filename = os.path.basename(image_path)

    with open(image_path, "rb") as f:
        headers = {
            "Content-Disposition": f'attachment; filename="{filename}"',
            "Content-Type": "image/png",
        }

        response = session.post(
            endpoint,
            headers=headers,
            data=f,
            timeout=60,
        )

    response.raise_for_status()
    media = response.json()

    return media["id"]


def set_featured_image(
    base_url: str,
    username: str,
    app_password: str,
    post_id: int,
    media_id: int,
):

    session = requests.Session()
    session.auth = HTTPBasicAuth(username, app_password)

    endpoint = f"{base_url.rstrip('/')}/wp-json/wp/v2/posts/{post_id}"

    payload = {
        "featured_media": media_id
    }

    response = session.post(endpoint, json=payload, timeout=30)
    response.raise_for_status()

    return response.json()


if __name__ == "__main__":

    image_path = "thumbnail.png"

    media_id = upload_media(
        base_url=WP_BASE_URL,
        username=WP_USERNAME,
        app_password=WP_APP_PASSWORD,
        image_path=image_path,
    )

    set_featured_image(
        base_url=WP_BASE_URL,
        username=WP_USERNAME,
        app_password=WP_APP_PASSWORD,
        post_id=post["id"],
        media_id=media_id,
    )

    print("アイキャッチ画像を設定しました")

まとめ

手動でアイキャッチ画像を設定する手間を省き、WordPress REST APIを活用した自動化プロセスを構築しました。

既存プラグインとの比較を踏まえ、自作ツールの選択が可能となり、記事内容変更時のサムネイル最適化を実現しています。

この仕組みにより、運用負担を大幅に軽減し、常に最適なサムネイルが表示されるようになります。

タイトルとURLをコピーしました