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つ以上の特定のスラッグを持つ用語に制限 | 
 
  
  
  
  

コメント
posipochi.com
posipochi.com