概要
Python から WordPress ブログにコンテンツを投稿したり、画像をアップロードするといった各種操作を行う方法について解説します。 これらの操作は WordPress が提供している XML-RPC API を介して行います。
XML-RPC による通信は、標準ライブラリの xmlrpc.client でもできますが、今回は WordPress への XML-RPC による通信をライブラリ化した python-wordpress-xmlrpc を使って行います。
XML-RPC と WordPress API
XML-RPC は HTTP 経由で、XML を使って遠隔手続き呼び出しを実現する方法です。 WordPress は、コンテンツの投稿や更新といった各種操作を他のアプリケーションから行えるように、XML-RPC を介した API を提供しています。 API の仕様は XML-RPC WordPress API で確認できます。
インストール
pip
でインストールできます。
pip install python-wordpress-xmlrpc
クライアントの作成
まず、通信を行うクライアントを作成します。
Client(url, username, password)
- 引数
- url:
xmlrpc.php
の URL を指定します。
ブログのログイン画面がhttps://sample.info/wp/wp-admin/
だとすると、xmlrpc.php
はhttps://sample.info/wp/xmlrpc.php
にあります。 - username: ログイン時のユーザー名
- password: ログイン時のパスワード
- url:
from getpass import getpass
from wordpress_xmlrpc import Client, WordPressPost, methods
url = "https://pystyle.info/wp/xmlrpc.php"
user = getpass("ユーザー名")
password = getpass("パスワード")
client = Client(url, user, password)
コンテンツの操作
python-wordpress-xmlrpc は、投稿など実行したい操作を表す Methods オブジェクトを作成し、それを Client.call() に渡して呼び出す Command パターン のインタフェースになっています。
タイトル | 概要 |
---|---|
methods.posts.GetPosts | コンテンツ一覧を取得する。 |
methods.posts.GetPost | 特定のコンテンツを取得する。 |
methods.posts.NewPost | コンテンツを投稿する。 |
methods.posts.EditPost | 既存のコンテンツを編集する。 |
methods.posts.DeletePost | コンテンツ、添付ファイルを削除する。 |
methods.posts.GetPostStatusList | コンテンツの状態 post_status がとり得る値の一覧を返します。 |
methods.posts.GetPostFormats | コンテンツの形式 post_format がとり得る値の一覧を返します。 |
methods.posts.GetPostTypes | コンテンツの種類 post_type がとり得る値の一覧を返します。 |
コンテンツ一覧を取得する。
methods.posts.GetPosts を使うと、ブログ上のコンテンツ一覧を取得できます。
methods.posts.GetPosts([filter, fields])
- 引数
- filter: フィルタ条件
- fields: 取得する項目
filter
には取得する際の条件を dict で指定します。
{
"number": 取得する最大数,
"offset": オフセット,
"orderby": ソートに使用する項目,
"order": ソート順序 ("ASC": 昇順, "DESC": 降順),
"post_type": コンテンツの種類 ("post": 記事, "page": 固定ページ)
"post_status": コンテンツの状態 ("publish": 公開中, "draft": 下書き),
}
コンテンツを n 個ずつ取得する
コンテンツを n 個ずつ取得したい場合は、フィルタ条件で number
と offset
を使用します。
# 20件ずつ取得したい場合、
number = 20 # 一度に取得するコンテンツ数
offset = 0 # オフセット
while True:
posts = client.call(methods.posts.GetPosts({"number": number, "offset": offset}))
if len(posts) == 0:
break # これ以上取得するコンテンツがない場合
for post in posts:
print(post.id, post.title)
offset += number
1750 matplotlib - カラーマップを自作する方法について 1332 OpenCV - 画像をグリッド上に分割する、複数の画像をグリッド上に結合する方法 850 OpenCV - 画像処理の2値化の仕組みと cv2.threshold() の使い方 693 物体検出で使われる評価指標 mAP について解説 671 Python - 顔認識ライブラリ Face Recognition で顔検出を行う方法 665 matplotlib - コピペするだけで matplotlib を日本語化する方法 (Windows / Ubuntu 対応) 643 Python - 顔認識ライブラリ Face Recognition で顔認証を行う方法 600 Python から XML-RPC を介して WordPress を操作する方法 544 Pytorch - Fashion-MNIST で CNN モデルによる画像分類を行う 55 2020年版 Deep Learning ライブラリの選び方
記事を取得する順番を変更する
デフォルトでは、投稿日時が最新のコンテンツから取得するようになっていますが、orderby
でソートする項目を変更できます。
また、order
でソートを降順でするか、昇順でするかを変更できます。
# 更新日時が古い順に取得する。
posts = client.call(
methods.posts.GetPosts({"orderby": "post_modified", "order": "ASC"})
)
for post in posts:
print(post.id, post.title)
1332 OpenCV - 画像をグリッド上に分割する、複数の画像をグリッド上に結合する方法 544 Pytorch - Fashion-MNIST で CNN モデルによる画像分類を行う 643 Python - 顔認識ライブラリ Face Recognition で顔認証を行う方法 600 Python から XML-RPC を介して WordPress を操作する方法 671 Python - 顔認識ライブラリ Face Recognition で顔検出を行う方法 693 物体検出で使われる評価指標 mAP について解説 850 OpenCV - 画像処理の2値化の仕組みと cv2.threshold() の使い方 665 matplotlib - コピペするだけで matplotlib を日本語化する方法 (Windows / Ubuntu 対応) 55 2020年版 Deep Learning ライブラリの選び方 1750 matplotlib - カラーマップを自作する方法について
特定のコンテンツを取得する
methods.posts.GetPost を使うと、指定した ID のコンテンツを直接取得できます。 返り値は、コンテンツの情報を表す WordPressPost オブジェクトです。
methods.posts.GetPost(post_id[, fields])
- 引数
- post_id: コンテンツ ID
- fields: 取得する項目
WordPressPost オブジェクトの属性、XML-RPC WordPress API の項目の対応表
XML-RPC 上の項目 | WordPressPost の属性 | 意味 |
---|---|---|
post_id | id | ID |
post_title | title | タイトル |
post_date | date | 作成日時 |
post_date_gmt | – | 作成日時 (GMT) |
post_modified | date_modified | 更新日時 |
post_modified_gmt | – | 作成日時 (GMT) |
post_status | post_status | 状態 (“publish”: 公開中, “draft”: 下書き) |
post_type | post_type | 種類 (“post”: 記事, “page”: 固定ページ) |
post_format | post_format | 形式 |
post_name | slug | スラグ |
post_author | user | 投稿したユーザー ID |
post_password | password | 閲覧パスワード |
post_excerpt | excerpt | 概要 |
post_content | content | 内容 |
post_parent | parent_id | 親コンテンツの ID |
post_mime_type | mime_type | minetype |
link | link | URL |
guid | guid | URL (ID) |
menu_order | menu_order | メニューオーダー |
comment_status | comment_status | コメントを受け付けるかどうか (“open”: 受付, “close”: 閉鎖) |
ping_status | ping_status | ピンを受け付けるかどうか (“open”: 受付, “close”: 閉鎖) |
sticky | sticky | ブログトップに固定するかどうか |
post_thumbnail | thumbnail | アイキャッチ画像 |
terms | terms | カテゴリ及びタグ |
terms_names | ||
custom_fields | ||
enclosure |
import pandas as pd
fields = [
["ID", "id"],
["タイトル", "title"],
["作成日時", "date"],
["更新日時", "date_modified"],
["状態", "post_status"],
["種類", "post_type"],
["形式", "post_format"],
["スラグ", "slug"],
["投稿したユーザー ID", "user"],
["閲覧パスワード", "password"],
["概要", "excerpt"],
# ["内容", "content"],
["親コンテンツの ID", "parent_id"],
["minetype", "mime_type"],
["URL", "link"],
["URL (ID)", "guid"],
["メニューオーダー", "menu_order"],
["コメントを受け付けるかどうか", "comment_status"],
["ピンを受け付けるかどうか", "ping_status"],
["ブログトップに固定するかどうか", "sticky"],
# ["アイキャッチ画像", "thumbnail"],
# ["カテゴリ及びタグ", "terms"],
]
post = client.call(methods.posts.GetPost(544))
df = []
for name, attr in fields:
df.append({"属性名": attr, "内容": name, "値": getattr(post, attr)})
pd.DataFrame(df)
属性名 | 内容 | 値 | |
---|---|---|---|
0 | id | ID | 544 |
1 | title | タイトル | Pytorch – Fashion-MNIST で CNN モデルによる画像分類を行う |
2 | date | 作成日時 | 2020-02-16 16:34:56 |
3 | date_modified | 更新日時 | 2020-03-15 14:54:25 |
4 | post_status | 状態 | publish |
5 | post_type | 種類 | post |
6 | post_format | 形式 | standard |
7 | slug | スラグ | pytorch-cnn-based-classification-model-with-fa… |
8 | user | 投稿したユーザー ID | 1 |
9 | password | 閲覧パスワード | |
10 | excerpt | 概要 | |
11 | parent_id | 親コンテンツの ID | 0 |
12 | mime_type | minetype | |
13 | link | URL | https://pystyle.info/pytorch-cnn-based-classif… |
14 | guid | URL (ID) | https://pystyle.info/?p=544 |
15 | menu_order | メニューオーダー | 0 |
16 | comment_status | コメントを受け付けるかどうか | open |
17 | ping_status | ピンを受け付けるかどうか | open |
18 | sticky | ブログトップに固定するかどうか | False |
コンテンツを投稿する
まず、WordPressPost オブジェクトを作成し、コンテンツのタイトルや内容を各属性に設定します。 設定できたら、methods.posts.NewPost を使い、コンテンツを投稿できます。 投稿に成功すると、コンテンツ ID が返ります。
methods.posts.NewPost(content)
- 引数
- content: コンテンツ
- 返り値
- コンテンツ ID
# コンテンツを作成する。
post = WordPressPost()
post.title = "新しい記事"
post.content = "記事の内容"
post.terms_names = {"post_tag": ["Python", "WordPress"], "category": ["Python"]}
# コンテンツを投稿する。
post_id = client.call(methods.posts.NewPost(post))
print(post_id)
1824
既存のコンテンツを編集する。
methods.posts.EditPost を使用すると、指定した ID のコンテンツを上書きできます。
まず、methods.posts.GetPost で編集したいコンテンツを取得し、返り値の WordPressPost オブジェクトの編集したい属性を変更します。 変更したら、methods.posts.EditPost を使い、コンテンツを上書きできます。
methods.posts.EditPost(post_id, content)
- 引数
- post_id: 上書きするコンテンツの ID
- content: コンテンツ
- 返り値
- 上書きに成功した場合は True を返します。
# 編集するコンテンツを取得する。
post = client.call(methods.posts.GetPost(post_id))
post.title = "編集したタイトル"
post.content = "編集した内容"
# コンテンツを更新する。
ret = client.call(methods.posts.EditPost(post_id, post))
print(ret)
True
既存のコンテンツを削除する。
methods.posts.DeletePost を使用すると、指定した ID のコンテンツを削除できます。
methods.posts.DeletePost(post_id)
- 引数
- post_id: 削除するコンテンツの ID
- 返り値
- 削除に成功した場合は True を返します。
ret = client.call(methods.posts.DeletePost(post_id))
print(ret)
True
添付ファイルの操作
タイトル | 概要 |
---|---|
methods.media.UploadFile | 添付ファイルをアップデートする。 |
methods.media.GetMediaLibrary | 添付ファイル一覧を取得する。 |
methods.media.GetMediaItem | 特定の添付ファイルを取得する。 |
添付ファイルをアップロードする。
methods.media.UploadFile を使用すると、ブログで使用したい画像などをアップロードできます。
まず以下の辞書を作成します。
data = {
"post_id": 添付ファイルを紐付けるコンテンツ ID (任意)
"name": ファイル名,
"type": minetype,
"bits": データを表すバイト列から作成した xmlrpc_client.Binary オブジェクト
}
post_id
は任意なので、なくても構いません。
作成したら、methods.media.UploadFile を使い、データをアップデートできます。
methods.media.UploadFile(data)
- 引数
- data: アップデートするデータ
- 返り値
- アップロードに成功した場合は、ID や URL といった情報が格納された辞書が返ります。
import mimetypes
from pathlib import Path
from pprint import pprint
from wordpress_xmlrpc.compat import xmlrpc_client
# ファイルを読み込む。
filepath = Path("sample.png")
with open(filepath, "rb") as f:
binary = xmlrpc_client.Binary(f.read())
# ファイルの minetype を取得する。
minetype = mimetypes.guess_type(filepath)[0]
print(minetype)
data = {
"post_id": post_id, # 添付ファイルを紐付けるコンテンツ ID
"name": filepath.name, # WordPress 上のファイル名
"type": "image/jpeg", # mimetype
"bits": binary, # データ
}
# アップロードする。
res = client.call(methods.media.UploadFile(data))
print(f"添付ファイルの ID: {res['id']}")
print(f"WordPress 上のファイル名: {res['file']}")
print(f"WordPress 上の URL: {res['link']}")
print(f"添付ファイルが紐付いているコンテンツの ID: {res['parent']}")
attachment_id = res['id']
image/png 添付ファイルの ID: 1827 WordPress 上のファイル名: sample.png WordPress 上の URL: https://pystyle.info/wp/wp-content/uploads/2020/03/sample.png 添付ファイルが紐付いているコンテンツの ID: 1824
添付ファイル一覧を取得する
methods.media.GetMediaLibrary を使うと、添付ファイル一覧を取得できます。
methods.media.GetMediaLibrary(filter)
- 引数
- filter: フィルタ条件
filter
には取得する際の条件を dict で指定します。
{
"number": 取得する最大数,
"offset": オフセット,
"parent_id": 添付ファイルが紐付いているコンテンツの ID,
"mime_type": minetype,
}
# ID post_id に紐づく添付ファイル一覧を取得する。
files = client.call(methods.media.GetMediaLibrary({"parent_id": post_id}))
for file in files:
print(file.id, file.title)
1827 sample.png
特定の添付ファイルを取得する。
methods.media.GetMediaItem を使うと、指定した ID の添付ファイルを取得できます。 返り値は、添付ファイルの情報を表す WordPressMedia オブジェクトです。
methods.media.GetMediaItem(attachmend_id)
- 引数
- attachmend_id: 添付ファイル ID
WordPressMedia オブジェクトの属性、XML-RPC WordPress API の項目名の対応表
XML-RPC 上の項目名 | WordPressMedia の属性 | 意味 |
---|---|---|
attachment_id | id | ID |
date_created_gmt | date_created | 作成日時 (GMT) |
parent | parent | 紐付いているコンテンツの ID |
link | link | WordPress 上のURL |
title | title | WordPress 上のファイル名 |
caption | caption | 注釈 |
description | description | 説明 |
metadata | metadata | メタデータ |
thumbnail | thumbnail | サムネイルの URL |
import pandas as pd
fields = [
["ID", "id"],
["作成日時 (GMT)", "date_created"],
["紐付いているコンテンツの ID", "parent"],
["WordPress 上のURL", "link"],
["WordPress 上のファイル名", "title"],
["注釈", "caption"],
["説明", "description"],
["メタデータ", "metadata"],
["サムネイルの URL", "thumbnail"],
]
# ID post_id のコンテンツの添付ファイル一覧を取得する。
files = client.call(methods.media.GetMediaItem(attachment_id))
df = []
for name, attr in fields:
df.append({"属性名": attr, "内容": name, "値": getattr(files, attr)})
pd.DataFrame(df)
属性名 | 内容 | 値 | |
---|---|---|---|
0 | id | ID | 1827 |
1 | date_created | 作成日時 (GMT) | 2020-03-16 13:09:21 |
2 | parent | 紐付いているコンテンツの ID | 1824 |
3 | link | WordPress 上のURL | https://pystyle.info/wp/wp-content/uploads/202… |
4 | title | WordPress 上のファイル名 | sample.png |
5 | caption | 注釈 | |
6 | description | 説明 | |
7 | metadata | メタデータ | {‘width’: 512, ‘height’: 512, ‘file’: ‘2020/03… |
8 | thumbnail | サムネイルの URL | https://pystyle.info/wp/wp-content/uploads/202… |
既存の添付ファイルを削除する。
methods.posts.DeletePost は、コンテンツを削除する他、添付ファイルの削除も行えます。
post_id
に添付ファイルの ID を指定すると、削除できます。
ret = client.call(methods.posts.DeletePost(attachment_id))
print(ret)
True
コメント