Pythonを使ってWordPressに複数画像をupload する方法 [REST API]

Python

WordPressでの投稿を続けていると、前の記事をベースにリライトしたいとき、画像や中身の表現だけを少し変えて投稿したいなというときはございませんか?
私は毎週更新している [資産運用の週次報告] はその週の「本文の一部」「画像ファイル」「リンクURL」を差し替えて手動で更新しています。ある程度の型が決まっているため更新作業自体は30分ほどで終了できるのですが、今回その作業を自動化する方法をステップに分けて紹介して行きます。

本記事では「 Pythonを使ってWordPressに複数画像をupload 」する方法をコード付きで紹介したいと思います。

はじめに

WordPressで[資産運用の週次報告]のページのように実用的な自動投稿を実現するため本記事を含めて5つのステップに分けて解説していきます。

  1. PythonとWordPressを連携して記事の下書き投稿する
  2. PythonでWordPressに画像を追加
  3. PythonでWordPressに複数の画像を一括で追加 (本記事)
  4. PythonとJinja2でWordPress投稿記事を編集 (本文・画像追加・ギャラリー)
  5. REST APIでHTML文とアイキャッチ画像を設定して投稿する

各ステップの流れを一つの流れに整理すると以下のフロー図で示すことができ、本記事で紹介する範囲は黄色ハイライトした箇所です。複数の記事にまたがるとどの内容を見ているかを見失ってしまいやすいので、適宜このフローチャートを確認してください。

環境設定
◆ Mac OS
◆ Python 3
JupyterLab
◆ WordPress ver. 5.8

はじめに ひとつのメディアファイルをuploadする

メディアファイルをひとつのみuploadする方法はこちらの記事を参照ください。

Pythonを使ってWordPressに画像をupload する方法 [REST API]
Wordpressでの投稿を続けていると、前の記事をベースにリライトしたいとき、画像や中身の表現だけを少し変えて投稿したいなというときはございませんか? 私は毎週更新している はその週の「本文の一部」「画像ファイル」「リンクURL」を差...

本記事では「WP REST API」の設定も終わり、ひとつであればメディアファイルをuploadできている段階を想定しております。具体的な想定読者は、以下の悩みを持つ人たちです。

ある指定のフォルダ内にある全てのメディアファイルを一度にWordpressへuploadしたい。

WordPressへuploadするだけでなく最終的には記事中に入れたいから、そのための準備もしたい。

 

Pythonを使ってWordPressに複数画像をupload するコード

Pythonを使ってWordPressに複数画像をupload するには2つの段階 + αがあります。

  1. Uploadしたいファイルのパス一覧を取得する
  2. REST APIでWordpressにメディアファイルをuploadする
  3. メディアIDなどのmedia infoを整理する

それぞれ解説していきます。

 

Uploadしたいファイルのパス一覧を取得する

フォルダ中のファイルパス一覧を取得するには、[Pythonチートシート]中の「フォルダ中のファイル一覧を取得してcsvファイルに出力」を参考にします。

フォルダ中のファイル一覧を取得してcsvファイルに出力 [Pythonチートシート]
Pythonを使っていると複数のコードで共通して使用しているコードがあることに気付きます。その作業を完全に覚えていればいいのですが毎回ウェブで調べてコードを記述して、とすると目的の作業は同じなのにシートごとにコード記述方法が違ってしまい見に...

 

細かい説明は本記事中では割愛してパス一覧を取得するコードを紹介します。

import pandas as pd
import glob

# 1. フォルダ内のファイル名をすべて読み込む 
filepath_list_all = glob.glob('/Users/mark/xxx/*')

# 2. フォルダ内のファイル名で任意の文字列を含むファイルをすべて読み込む
date = '20220713' 
filepath_list_all = glob.glob('/Users/mark/xxx/' + date + '*')

# 空listの作成
filepath_list = []

# listに出力
for filepath in filepath_list_all:
    filepath_list.append(filepath)

# filepathをアルファベット順にsort
filepath_list.sort()
filepath_list

# # pandas dfに出力
# df = pd.DataFrame(file_list2, columns=['file_name'])
# df

 

4行目:フォルダ内の文字列全てを読み込む
ワイルドカードである*を用いることでフォルダ内のファイル全てを読み込みます。7行目:任意の文字列で始まるファイル名を全て読み込む
ワイルドカード検索の応用例として示しております。具体例として、uploadしたいファイルに全て共通の日付(上記例ではdate = 20220713)が入っている場合にそのファイルを読み込みます。18行目:アルファベット順にsort
Wordpressにuploadする際にファイルの種類とupload順を毎回同じ順番にするためにsort()を用います。理由としてはメディアファイルのupload順にmedia idと呼ばれるWordpress中での管理番号が付けられ、このmedia idがWordpress投稿時の「アイキャッチ画像」や「ギャラリー中に使用する画像」に必要なためです。

 

上記を実行すると任意のフォルダ(例では[xxx]というフォルダ名)の中で、[20220713]で始まるファイルパスを取得しfilepath_listというlistに収納することができました。

 

実行結果

['/Users/mark/Jupyter Lab/xxx/20220713_xxx.png',
'/Users/mark/Jupyter Lab/xxx/20220713_yyy.png',
'/Users/mark/Jupyter Lab/xxx/20220713_zzz.png']

REST APIでWordpressにメディアファイルをuploadする

ひとつ前の章でuploadしたいファイルのパス一覧を取得できたらあとは「メディアファイルをひとつのみuploadする方法」で紹介した関数を利用し、uploadしたいファイルの数分だけfor文でループ処理することでupload処理ができます。

Pythonを使ってWordPressに画像をupload する方法 [REST API]
Wordpressでの投稿を続けていると、前の記事をベースにリライトしたいとき、画像や中身の表現だけを少し変えて投稿したいなというときはございませんか? 私は毎週更新している はその週の「本文の一部」「画像ファイル」「リンクURL」を差...

詳細なコードの説明は上記記事を参照してもらい、Wordpressにメディアファイルをuploadする関数wp_upload_path_mediaのコードは以下の通りです。

MY_URL, MY_USER, MY_APP_PASSWORDと16行目 filenameをfilepathから取得する箇所の数字はご自身の環境に応じて変更する必要があるため注意ください。それらの注意点も含めてこちらの記事に記載してあります。

 

import requests
from urllib.parse import urljoin
import os
import json

# def設定: WordPressのメディアにファイルをupload
def wp_upload_path_media(filepath):
    # URL, User, Password設定
    MY_URL: str = "要変更https://hoge-hoge.com"
    MY_USER: str = "要変更user"
    MY_APP_PASSWORD: str = "要変更abcd efgh ijkl mnop qrst uvwx"

    url = urljoin(MY_URL, 'wp-json/wp/v2/media/')
    file_path = filepath
#     print('filepath: ' + file_path)
    filename = filepath[41:] # 数字はfilepathに応じて変更すること
#     print('filename: ' + filename)
    f = open(file_path, 'rb')
    image_data = f.read()
    f.close()

    headers = {
        'Content-Type': 'image/png',
        'Content-Disposition': 'attachment; filename=' + filename,
    }

    res = requests.post(
        url,
        data=image_data,
        headers=headers,
        auth=(MY_USER, MY_APP_PASSWORD),
        )
    media_info = res.json()
#     print(json.dumps(media_info, indent=4)) # uploadステータス(不要な場合はコメントアウト)
    media_id = media_info['id'] # アップロードした画像のID
    media_url = media_info['source_url'] # アップロードした画像のURL
    
    # 後にmedia情報を取得するためにlistとして各種情報を取得
    media_info_list = [filename, file_path, media_id, media_url]
    
    return [filename, file_path, media_id, media_url]

 

上記でメディアファイルをuploadする関数wp_upload_path_mediaを定義したのち、uploadしたいファイルの数分だけfor文でループ処理することでupload処理を行います。

# list中の項目の説明
media_info_list = [['filename', 'filepath', 'media_id', 'media_url']]

for filepath in filepath_list:
    media_upload = wp_upload_path_media(filepath)
#     print(media_upload)
    media_info_list.append(media_upload)
media_info_list

 

1,2行目 listの先頭に項目名の設定
media_info_listにuploadしたメディアファイルの各情報をappend()で追加する際に、どの順番で何の情報を記載しているかがわかるように追加しました。
実行結果
[['filename', 'filepath', 'media_id', 'media_url'],
 ['20220713_xxx.png',
  '/Users/mark/xxx/20220713_xxx.png',
  1,
  'https://life100create.com/wp-content/uploads/2022/07/20220713_xxx.png'],
 ['20220713_yyy.png',
  '/Users/mark/xxx/20220713_yyy.png',
  2,
  'https://life100create.com/wp-content/uploads/2022/07/20220713_yyy.png'],
 ['20220713_zzz.png',
  '/Users/mark/xxx/20220713_zzz.png',
  3,
  'https://life100create.com/wp-content/uploads/2022/07/20220713_zzz.png']]

 

関数として定義したコードを実行すると、投稿が無事に追加された場合には以下のlistが返され、「ファイル名 filename」「パス名 file_path」「メディアID media_id」「メディアURL media_url」が取得できました。

またWordPressの「メディア」を確認するとちゃんとコードで指定したファイルがメディアファイルとしてuploadされたことが確認できます。

ここまででWordpressに複数のメディアファイルをupkoadすることができましたが、次の「画像つき記事を投稿する」前にもうひとつ+αの準備をします。それが「メディアIDなどのmedia infoを整理する」ことです。

 

メディアIDなどのmedia infoを整理する

「メディアID media_id」「メディアURL media_url」はこの次に「画像入りの記事をREST APIで自動投稿する」際に必要です。それぞれのメディアID、メディアURLをどのように本文記事(HTML)やアイキャッチ画像の投稿に使用するかは以下に例とHTMLを併記しました。

メディアID media_id:アイキャッチ画像、ギャラリーに必要

アイキャッチ画像:

REST APIで投稿時にmedia_idを指定することで設定されます。

# 投稿設定: post
    post = {
                'title': '資産の見える化 ウィークリーレポート <' + date[0:4] + '年' + date[4:6] + '月' + date[6:8] + '日週>',#投稿記事タイトル
                'status': 'draft',#ステータス 公開:publish, 下書き:draft
                'content': content,
                'categories': [140],#カテゴリーID
                'tags': [202],#タグID
                'slug': 'weekly_' + date + '/',#URLスラッグ
                'featured_media': eyecatch_id, # アイキャッチのID
            }

ギャラリー:

HTML中にギャラリーとして表示したい画像のmedia_idを指定することで本文中に反映されます。

ギャラリーHTML:
gallery ids="1,2,3"

メディアURL media_url:記事中の埋め込み画像に必要

HTML中のsrc=media_urlを指定することで本文中に表示されます。

記事中の埋め込み画像HTML:
<img class="aligncenter size-full wp-image-4585" src="https://life100create.com/wp-content/uploads/2022/07/test.png" alt="" width="427" height="273" />
先のコードで得られたmedia_info_listを扱いやすいように処理しておきます。

この整理のやり方は人それぞれの好みがあるかと思いますが、私はlistpandas dataframeに変換し、他実行ファイルからも読み取れるようにcsvファイルで保存しております。理由としてはdataframeにした方がmedia_idとファイル名の対応がつきやすいからです。

import pandas as pd

media_info_df = pd.DataFrame(media_info_list)
media_info_df.to_csv('media_info.csv',header=False, index=False)

これでmedia_info.csvファイルが作成されました。

次のステップに向けて

今回は「 Pythonを使ってWordPressに複数画像をupload 」を実行するための「pythonのコード」を紹介しました。

WordPressで[資産運用の週次報告]のページのように実用的な自動投稿を実現するためのステップは以下の通りです。

  1. PythonとWordPressを連携して記事の下書き投稿する
  2. PythonでWordPressに画像を追加
  3. PythonでWordPressに複数の画像を一括で追加 (本記事)
  4. PythonとJinja2でWordPress投稿記事を編集 (本文・画像追加・ギャラリー)
  5. REST APIでHTML文とアイキャッチ画像を設定して投稿する

次回は、PythonでWordPress投稿記事を編集 (本文・画像追加・ギャラリー画像の設定)する方法について紹介したいと思います。

コメント

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