PythonでWordPressに投稿するサンプル【REST APIを利用】

WordPressの REST API を使って、Pythonによる記事の投稿と更新のサンプルです。タグの一覧の取得や追加もあります。

記事投稿は、XML-RPC と REST API の二通りがあるのですが、このような理由で REST API に決めました。

  • XML-RPCは、XServerがデフォルトでアクセス不可にしている
  • REST APIの方が後発で、ver. 4.4から標準搭載

ちなみに、どちらもプラグインの追加なしに使えます。

REST API利用前の準備

記事の追加・更新・削除のあるユーザー権限でPythonから操作すると、セキュリティ上好ましくない事態が起こりえます。そのため、WordPressのログイン画面から入れない新規のパスワードを作って、そのパスワードでAPIを利用します。

WordPressのユーザーのプロフィールの下の方にある、「アプリケーションパスワード」に「新しいアプリケーションパスワード名」に好きな文字(アプリエーション名)を入れて「新しいアプリケーションパスワードを追加」を押下します。

20文字の新しいパスワードが生成されます。アプリケーションは、これを利用してWordPressにアクセスします。

PythonからWordPressを操作するサンプル

WordPressのユーザーと先ほど追加した20桁のパスワードを利用します。

各サンプルに共通するモジュール読み込みと定数

import requests
import json
import base64

MY_URL: str = "https://hoge-hoge.com"
MY_USER: str = "user"
MY_APP_PASSWORD: str = "abcd efgh ijkl mnop qrst uvwx"

記事を追加


def wp_create_post() -> dict:

    credentials = MY_USER + ':' + MY_APP_PASSWORD
    token = base64.b64encode(credentials.encode())
    headers = {'Authorization': 'Basic ' + token.decode('utf-8')}

    post = {
                'title': 'Hello World',
                'status': 'draft',  # publish',
                'content': 'テスト',
                'categories': [5],
                'tags': [189, 148],
                'slug': 'pre_open',
            }

    res = requests.post(f"{MY_URL}/wp-json/wp/v2/posts/", headers=headers, json=post)
    if res.ok:
        print("投稿の追加 成功 code:{res.status_code}")
        return json.loads(res.text)
    else:
        print(f"投稿の追加 失敗 code:{res.status_code} reason:{res.reason} msg:{res.text}")
        return {}

postに設定できる項目と値は、記事操作のスキーマにあります。

res.okが真の時、res.textに投稿したデータが入ってきています。JSON形式です。偽だった時、原因のヒントがres.textで得られます。パラメータが不足していたとしたら、その名前まで教えてくれて、気が利いていて助かります。

記事の更新

一度投稿したものを更新するサンプルです。記事のIDをキーにして更新します。


def wp_update_post() -> dict:
    credentials = MY_USER + ':' + MY_APP_PASSWORD
    token = base64.b64encode(credentials.encode())
    headers = {'Authorization': 'Basic ' + token.decode('utf-8')}

    post = {
               'title': 'Hello World',
               'status': 'publish',
               'content': '更新テスト',
            }

    post_id: int = 777
    res = requests.post(f"{MY_URL}/wp-json/wp/v2/posts/{post_id}", headers=headers, json=post)
    if res.ok:
        print("投稿の更新 成功 code:{res.status_code}")
        return json.loads(res.text)
    else:
        print(f"投稿の更新 失敗 code:{res.status_code} reason:{res.reason} msg:{res.text}")
        return {}

postに設定できる項目と値は、記事操作のスキーマにあります。

res.okが真の時、res.textに投稿したデータが入ってきています。JSON形式です。

記事操作のスキーマ

追加や更新のパラメータとして、戻り値の確認として使えます。戻り値は、取得時にフィルターが掛けられていると入ってきません。

名称 説明
date string or null / datetime (details) 公開された日付(サイトのタイムゾーン)
date_gmt string or null / datetime (details) 公開された日付(GMT)
guid object 識別子 読み取り専用
id integer 記事ID 読み取り専用
link string,uri URL 読み取り専用
modified string,datetime (details) 最後に変更された日付(サイトのタイムゾーン) 読み取り専用
modified_gmt string,datetime (details) 最後に変更された日付(GMT) 読み取り専用
slug string 投稿記事のスラグ(ユニーク)
status string 投稿記事の状態
type string 投稿記事のタイプ
password string 投稿記事へのアクセスパスワード
permalink_template string パーマリンクテンプレート 読み取り専用
generated_slug string 自動生成されたスラグ 読み取り専用
title object 投稿記事のタイトル
content object 投稿記事の本文
author integer 投稿者ID
excerpt object 投稿記事の抜粋
featured_media integer アイキャッチ画像のID
comment_status string コメントを許すかどうか One of: open, closed
ping_status string pingを許すかどうか One of: open, closed
format string 投稿記事のフォーマット One of: standard, aside, chat, gallery, link, image, quote, status, video, audio
meta object メタ情報
sticky boolean スティッキーとして扱う必要があるとき真
template string 記事のテーマ名
categories array カテゴリーのリスト
tags array タグのリスト

categories と tags の型は、arrayになっていますが、各項目はタグのID、つまり整数のみです。WordPressで記事投稿する時はタグの文字列を設定できますが、REST-APIはできません。そのため、ないタグで投稿する場合、新規にタグを追加した後になります。

formatに関しては、WordPress公式(日本)が詳しく書いてあります。

タグのリストの取得

タグ一覧を取得するサンプルです。一度に取得できるのは、最大で100個までで、それ以上になるとページを切り替えて取得しなければなりません。

def wp_get_tag_list() -> List[dict]:

    tag_list: List[dict] = []

    page: int = 1
    while True:
        res = requests.get(f"{MY_URL}/wp-json/wp/v2/tags/?per_page=100&page={page}")
        if res.ok:
            print("タグ取得 成功 code:{res.status_code}")
            items = json.loads(res.text)

            if 0 == len(items):
                return tag_list

            tag_list.extend(items)

            page += 1
        else:
            print(f"タグ取得 失敗 code:{res.status_code} reason:{res.reason} msg:{res.text}")
            return []

記事の投稿と同様に、res.OKが真の時、res.textにJSONで値が入ってきます。偽の時は、res.textにその理由が入ってきます。res.reasonより詳しいです。

タグの追加

新規にタグを追加するサンプルです。通常slugは、nameの小文字が設定されます。

def wp_create_tag() -> dict:

    credentials = MY_USER + ':' + MY_APP_PASSWORD
    token = base64.b64encode(credentials.encode())
    headers = {'Authorization': 'Basic ' + token.decode('utf-8')}

    post = {
        'description': '',
        'name': '新規タグ',
        'slug': 'abc',
        'meta': []
    }

    res = requests.post(f"{MY_URL}/wp-json/wp/v2/tags/", headers=headers, json=post)
    if res.ok:
        print("タグ追加 成功 code:{res.status_code}")
        return json.loads(res.text)
    else:
        print(f"タグ追加 失敗 code:{res.status_code} reason:{res.reason} msg:{res.text}")
        return {}

タグ操作のスキーマ

context クエストが行われる範囲。応答に存在するフィールドを決定します。 One of: view, embed, edit
page 現在のページ番号。1から開始。Default: 1
per_page 1ページで取得できる最大アイテム数。 Default: 10
search 結果セットに文字列に一致するものに限定
exclude 結果セットから特定IDを除外
include 結果セットの内、特定IDに制限
offset 結果セットを特定の数のアイテムでオフセット
order 昇順または降順で並べ替え Default: asc One of: asc, desc
orderby 用語属性で並べ替え Default: name One of: id, include, name, slug, include_slugs, term_group, description, count
hide_empty 全ての投稿に割り当てられていない用語を非表示にするかどうか
post 結果セットを特定の投稿に割り当てられた用語に制限
slug 結果セットを1つ以上の特定のスラッグを持つ用語に制限

コメント

  1. […] PythonでWordPressに投稿するサンプル【REST APIを利用】 WordPressの REST API を使っ… […]

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