Python スクレイピング

【Python】WordPressのREST APIを使ってブログに記事を自動投稿する

この記事は約9分で読めます。

 

こんにちは、ミナピピン(@python_mllover)です!

今回はワードプレスのrest apiを使用してブログに記事を自動投稿する方法について紹介したいと思います。

 

事前設定

 

まずワードプレスのプラグイン⇒新規追加からプラグインの「Application Passwords」をインストールして有効化します。

 

 

するとユーザ設定の画面にアプリケーションパスワードという項目が追加されます。

 

 

エックスサーバーなどでデフォルトの設定でワードプレスをインストールしていると恐らく、警告文のようなものが表示された状態だと思います。これを解消するためにはレンタルサーバーの管理画面で.htaccessを編集する必要があります。(詳細は↓)

 

WordPress REST APIの401エラーの解決法

 

WordPress REST APIで自動投稿した際に、
HTTP/1.1 100 Continue HTTP/1.1 401 Unauthorized Server: ・・・・・・{“code”:”rest_cannot_create”,”message”:”\u3053\u306e\u30e6\u30fc\u30b6\u30fc\u3068\u3057\u3066\u6295\u7a3f\u3092\u7de8\u96c6\u3059\u308b\u6a29\u9650\u304c\u3042\u308a\u307e\u305b\u3093\u3002″,”data”:{“status”:401}}
といったエラーが出て、投稿に失敗することがありました。

 

(原因)
WordPressの「ユーザー」→「プロフィール」→「アプリケーションパスワード」の上段に以下のようなメッセージがある場合、原因はサーバー設定のミスなので.htaccessの編集が必要です。

”Due to a potential server misconfiguration, it seems that HTTP Basic Authorization may not work for the REST API on this site: Authorization headers are not being sent to WordPress by the web server. You can learn more about this problem, and a possible solution, on our GitHub Wiki.”

 

(解決方法)
サーバー管理画面から.htaccessを以下のように編集してください。

# BEGIN WordPress
# "BEGIN WordPress" から "END WordPress" までのディレクティブ (行) は
# 動的に生成され、WordPress フィルターによってのみ修正が可能です。
# これらのマーカー間にあるディレクティブへのいかなる変更も上書きされてしまいます。

RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

# END WordPress
SetEnvIf Request_URI ".*" Ngx_Cache_NoCacheMode=off
SetEnvIf Request_URI ".*" Ngx_Cache_AllCacheMode
SetEnvIf Request_URI ".*" AllowRestApi

 

Home · WordPress/application-passwords Wiki
Contribute to WordPress/application-passwords development by creating an account on GitHub.

 

主な変更点は「RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]」です。これでapiでの認証情報のやり取りを可能にします。

 

設定変更したあとは再度、「ユーザー」→「プロフィール」→「アプリケーションパスワード」を確認し、
以下のように以前のエラーメッセージが消えていれば、認証設定はクリアです。

 

 

そしたら、次はタブに適当なワードを入力してadd newをクリックしてください。すると以下のように24個の文字列が発行されます。これがAPI鍵のようなものになりますので外部に漏れないようにしてください。

 

 

REST API制限の403エラーの解消法

 

403なので認証自体は通っているが権限周りでエラーが出ている状態。リクエストの形などは基本的にエラー原因とはならない。

 

レンタルサーバー側のREST API権限の問題

 

またローカルのPCではなくgooglecolabtryなどのクラウドサーバー上でワードプレスのREST APIを叩こうとすると403でアクセスが弾かれることがあります。

 

その場合はREST APIのアクセス制限設定がONになっていないかを確認してください。ちなみにエックスサーバーだと管理画面⇒Wordpressセキュリティ設定で確認することができます。ONの場合は↓画面のようにRESTAPI アクセス制限をOFFにしてください。

 

 

rest_cannot_assign_term

 

またタグをインデックス指定する際に存在しないタグ(既存タグ数よりも多いインデックスを指定する)と投稿時に新規タグを作成しようとするがタグ作成権限がないとと403:rest_cannot_assign_termになる。解決方法はタグのインデックスを既存タグの範囲内にするもしくは空のリスト=[]にすること。

 

 

スポンサーリンク
スポンサーリンク

PythonでWordPressにREST API経由で記事を自動投稿する

 

これで事前準備は終わったので、いよいよPythonのコードを叩いてスクリプト上からワードプレスに記事を投稿してみましょう。

 

# WordPress接続情報
WP_URL = 'https://tkstock.site/' #サイトトップのURL
WP_USERNAME = 'test' #ワードプレス管理画面ログイン時のユーザネーム
WP_PASSWORD = 'xxxx xxxx xxxx xxxx xxxx xxxx' #先ほど発行した24の文字列

# 投稿内容
title = 'テスト投稿'
html_text = '<p>テスト投稿です。</p>'
# WordPress新規投稿関数
def post_article(status, slug, title, content, category_ids, tag_ids, media_id):
    # REST APIを使うための認証情報
    user_ = WP_USERNAME
    pass_ = WP_PASSWORD
    # 投稿記事情報
    payload = {"status": status,                     #ステータス 公開:publish, 下書き:draft
              "slug": slug,                         #URLスラッグ
              "title": title,                       #タイトル
              "content": content,                   #内容
              "date": datetime.now().isoformat(),   #投稿日時
              "categories": category_ids,           #カテゴリー
              "tags": tag_ids}                      #タグ
    if media_id is not None:
        payload['featured_media'] = media_id         #アイキャッチ画像

    # 記事の新規投稿を行う
    res = requests.post(urllib.parse.urljoin(WP_URL, "wp-json/wp/v2/posts"),     #"wp-json/wp/v2/posts"にPostすると新規投稿になる
                       json=payload,                                            #投稿する記事の内容を設定する
                       auth=(user_, pass_))                                   #ユーザ、パスワードを設定する
    
    return res


# 記事を下書き投稿する
res = post_article('draft',
                   '東京-五輪-開会式-なだぎ武-意味不明',
                   title,
                   html_text,
                   category_ids=[0],
                   tag_ids=[0],
                   media_id=None)

print(res) #レスポンスが201だったら成功、それ以外(401など)だったら失敗

 

“wp-json/wp/v2/posts”の他の引数については以下参照↓

https://ja.wp-api.org/reference/posts/

 

 

 

 

コメント

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