環境
- Windows 10
- Python 3.10.1
- VSCode
使用するソースコード
以下の公開リポジトリに置いています
GitHub - masayan1126/tao-py-py: 作業自動化用 Python ライブラリ
作業自動化用 Python ライブラリ. Contribute to masayan1126/tao-py-py development by creating an account on GitHub.
実装方法
WordPressのrest-apiのドキュメントによると、記事一覧の取得APIのエンドポイントは、https://example.com/wp-json/wp/v2/postsになるので、こちらに対してpythonのプログラムからrequestsモジュールでHttpリクエストを送ればOKです

masayan
公式ドキュメントのAPIリファレンスはこちらです。
Whttps://developer.wordpress.org/rest-api/reference/
呼び出し側
- wordpressのエンドポイントを生成し、それをwp管理用の自作クラスに渡しています
- fetch_posts()にはページの指定ができるようにしていますが、デフォルトは全件取得のためNoneにしています
from shared.Domain.Wp.wp_operator import WpOperator
blog_url = "https://maasaablog.com/"
api_url = blog_url + "/wp-json/wp/v2/posts"
wp = WpOperator(api_url=api_url)
posts = wp.fetch_posts(page_number=None)
記事の取得処理
- オブジェクト生成時に、wordpressのエンドポイントとなるurlを受け取ります
- レスポンスヘッダ―に記事の全件数とページ数が入っているのでそれらを取得できるメソッドを実装します
- 総ページ数はレスポンスヘッダの[“X-WP-TotalPages”]
- 総記事数はレスポンスヘッダの[“X-WP-Total”]
- fetch_postsでは、呼び出し側から受け取ったページ数の指定がなければ全件取得し、ページ指定があれば、そのページの記事を取得するようにしています
- 実際にエンドポイントを叩く処理はpythonのrequestsモジュールのgetメソッドを使用しているだけです
from typing import List
import urllib.request, urllib.error
from shared.Domain.Wp.i_wp_operator import IWpOperator
import requests
from shared.Domain.xurl import XUrl
import json
from shared.Exception.wp_error import WpError
class WpOperator(IWpOperator):
def __init__(self, api_url: XUrl):
# urlがそもそも無効ならここで落とす
try:
f = urllib.request.urlopen(api_url)
self._api_url = api_url
except urllib.error.URLError as e:
raise e
finally:
if "f" in locals():
f.close()
def response_headers(self):
return requests.head(self._api_url).headers
def total_page_count(self) -> int:
try:
return int(self.response_headers()["X-WP-TotalPages"])
except KeyError as e:
raise WpError("This url is valid. But may not be a wordpress api url")
def total_posts_count(self) -> int:
try:
return int(self.response_headers()["X-WP-Total"])
except KeyError as e:
raise WpError("This url is valid. But may not be a wordpress api url")
def fetch_posts(self, page_number: int = None) -> List[dict]:
try:
posts = []
# ページ指定なし
if page_number is None:
_posts = []
for page_count in range(1, self.total_page_count() + 1):
res = requests.get(f"{self._api_url}?page={page_count}")
for post in json.loads(res.text): # JSON文字列を辞書型に変換
_posts.append(post)
else:
res = requests.get(f"{self._api_url}?page={page_number}")
_posts = json.loads(res.text) # JSON文字列を辞書型に変換
for post in _posts:
post_info = {
"title": post["title"]["rendered"],
"link": post["link"],
}
posts.append(post_info)
return posts
except requests.exceptions.HTTPError as e:
raise e

masayan
json.loadsの返り値は記事の配列ですが、1つ1つの記事は以下のような辞書型です
{‘id’: 4150, ‘date’: ‘2022-02-28T08:34:33’, ‘date_gmt’: ‘2022-02-27T23:34:33’, ‘guid’: {‘rendered’: ‘https://maasaablog.com/?p=4150’}, ‘status’: ‘publish’, ‘type’: ‘post’, ‘link’: ‘https://maasaablog.c…thon/4150/’, ‘title’: {‘rendered’: ‘Pythonでいい感じのロギングするためのTips’}, …}