wordpress APIで記事を投稿する

Hello World text python

もし、いつも記載する記事の形式が、毎回同じならば、プログラムで投稿出来れば楽ですよね。
わたしの場合、プログラミングと統計の勉強を趣味の競馬で行っていて、騎手ごとの画像データを載せたかったので、手動では無理があるため、プログラム的に投稿する必要がありました。

このブログ同様、まだクソブログですが、競馬に興味がある方は今後覗いてみてください。少しずつ見やすくしていきます。

【騎手分析】人気と着順の相関関係を可視化してみる
レースを見ていると、当然馬の強い弱いは前提としてあるもののやはり騎手による技量はとても大きい。そこで騎手ごとに人気×着順のヒートマップを作成してみた。データはだいたい2015年から2023年8月ごろまでx軸に着順、y軸に人気を配置した。基本

wordpress APIを使用するための準備

技術に乏しい私は、またテキトーにAPIキーを発行して、それでリクエストすればお終いと思ってましたが、認証やHTTPリクエストヘッダーなるものを設定しないといけなく、ちょっと手こずりました。

調査

まずは何をするにしても公式サイトを検索

【wordpress api document】でググる

日本語サイトもあるけど、更新が適当な気がするから英語版サイトを確認

なんやかんや書いてあるけどとりあえずUsingなんちゃらと書いてあるところを見る

エンドポイントは見つけた

/wp/v2/posts
/wp-json/wp/v2/posts

なんで2つあんねん。wp-jsonてなんやねん

読み進めると認証が必要とのこと。なんかややこしいし英語読めないし。。

とまぁイライラしながら試行錯誤した結果、(私が行った)手順は以下

認証方式を決定する

私はプラグインを使用したJWT Authenticationを選択。

他にはプラグインを使用したWordPress REST API – OAuth 1.0a Server

シンプルなBasic Authentication with Application Passwords

クッキーを使用したCookie Authentication などがあるようです。

認証については今度調べてまとめていきたいと思います。

プラグインを追加

ダッシュボードのプログインを追加から【JWT Authentication for WP REST API】を検索して有効化する

サーバーの設定

次がサーバーをいじるのが苦手な私には大変だった。

1.HTTP AUTHORIZATION HEADERを設定するのと

2.ワードプレスのwp-config.phpにJWT_AUTH_SECRET_KEYを設定する必要がある

webサーバがApacheかnginxかなどで異なる

私の上記の競馬ブログは ConohaのVPS 内のubuntuOSにnginxサーバを起動している そしてこの当サイトは バリュードメイン のXREAというサーバである
nginxの場合

/etc/nginx/sites-availableのサイトのファイルを開いて

locationブロックに以下の2文を追加する

fastcgi_pass_request_headers on;
fastcgi_param HTTP_AUTHORIZATION $http_authorization;

更新したらnginxを再起動するのをお忘れずに!

sudo systemctl reload nginx
Apacheの場合

サイトのルートディレクトリにある.htaccessファイルに以下の3文を加える必要がある

RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]

私のファイルには既に

RewriteRule .* – [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

という記載があるので入れないでもいいかな

wp-config.phpに追加

wp-config.phpに以下を追加する必要がある

define('JWT_AUTH_SECRET_KEY', 'your-top-secret-key');

your-top-secret-keyには一意の値を入れないといけないが、

シークレットキー生成サイトで、好きな文字列を取得して上書きすれば良い

上記サイトを更新すれば、また別のキーが生成されるので、確認後使用してください

プログラム作成とテスト

さて、ようやく実際にプログラムを走らせることができる。

認証情報のTokenを取得する

私はpythonでリクエストする

import requests
mysite = 'anata no site no url' # 私はhttps://www.beyoufree.com
endpoint = '/wp-json/jwt-auth/v1/token'
url = mysite + endpoint 

credentials = {
    "username": "site no user mei",
    "password": "user no pasuwa-do"
}

response = requests.post(url, data=credentials)


## ここで
response.ok # これがTrueなら認証Token取得成功!
token = response.json()['token'] # このあと使うためtoken変数に格納

## エラーなら
response.reason # 理由を確認

ここでエラーになることも多いと思うが、何かしらの設定ミスや漏れが原因であるので、

設定の再確認や認証に変更があるかもしれないので正しい設定を確認する必要がある。

ちなみに上記サイトで上から順番にやると圧縮ファイルをダウンロードしてwordpressにアップロードす手順があるが、先の手順でダッシュボードからプラグインをインストールした場合は競合してサイトがバグるので注意!

サンプル記事を投稿する

手始めにタイトルが【wordpressAPI test投稿】bodyが【ワードプレスAPIテスト中+このURLのリンク】と書いた記事をPOSTしてみる。

コードは以下

### 記事の内容
title = 'wordpressAPI test投稿'
parent_utl = 'anata no site'
contents = 'ワードプレスAPIテスト中\n'
contents += parent_utl

### 送信情報
api_url_post = "anata no site no url/wp-json/wp/v2/posts"

headers = {
    "Authorization": f"Bearer {token}" # 先程のtoken
}
post_data = {
    "title": title,
    "content": contents,
    "status": "publish"  # 公開しない場合は 'draft'
}

response_post = requests.post(api_url_post, headers=headers, json=post_data)
if response_post.status_code == 201:
    print("Post created successfully!")
    print(response_post.json())
else:
    print(f"Error: {response_post.status_code}")
    print(response_post.text)

投稿が成功すれば successfully と表示される

失敗した場合はエラーの内容をよく見て調べてほしい

実際にAPIで投稿したページ

URL部分が↑みたいにカードになると思ったけど自動ではならんのか。。

HTMLタグやCSSでちょっと改善

先程投稿した記事のURLをこのビジュアルエディタでURLをペーストした時に自動でカード表記してほしい。

一旦、この記事をリリースして、ブラウザの開発者ツールでどんな感じかみてみる

案の定blogcard-と書かれたclassが一杯ありますね

ちょっと長ったらしいですがfigureタグ内をコピーして、

URLとtitleとimage_urlをこの記事と同様にして、

再投稿してみましょう。以下が新しいcontentsなど

title = 'wordpressAPI test投稿2'
contents = '''
<p>ワードプレスAPIテスト中2</p>

<figure class="wp-block-embed is-type-wp-embed is-provider-beyou wp-block-embed-beyou"><div class="wp-block-embed__wrapper"><a href="https://www.beyoufree.com/2023/10/17/wordpress-api-post1/" title="wordpress APIで記事を投稿する" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img src="http://www.beyoufree.com/wp-content/uploads/2023/10/67l18r4tw_w.jpg" alt="" class="internal-blogcard-thumb-image" width="160" height="90"></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">wordpress APIで記事を投稿する</div><div class="blogcard-snippet internal-blogcard-snippet">プログラムで投稿出来れば楽ですよね</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img src="https://www.google.com/s2/favicons?domain=www.beyoufree.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16"></div><div class="blogcard-domain internal-blogcard-domain">www.beyoufree.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2023.10.17</div></div></div></div></a></div></figure>
'''

post_data = {
    "title": title,
    "content": contents,
    "status": "publish"  # 公開しない場合は 'draft'
}

response_post = requests.post(api_url_post, headers=headers, json=post_data)
response_post.status_code 

結果

いい感じに相互リンクが出来てるぜ!

改善と今後

まず共通の課題は、

記事のサムネイルやスラッグ、カテゴリやタグといったところ。

まぁこれはすぐにできるだろうから、のちほど更新します。

そしてこのあと、テンプレを作成して、タイトルと文章とサムネだけ変えて投稿するためには、先程のように現在使用しているテーマがどのようなHTML構造をしているかやclass名をつけているかをツールを使用して確認し、モジュール化していく必要があるが、効率化は楽しそうなので今後もやっていく

仕事依頼は最近ランサーズやココナラで引き受けているので、ご連絡ください。

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