私は毎週更新している [資産運用の週次報告] はその週の「本文の一部」「画像ファイル」「リンクURL」を差し替えて手動で更新しています。ある程度の型が決まっているため更新作業自体は30分ほどで終了できるのですが、今回その作業を自動化する方法をステップに分けて紹介して行きます。
以前「 Pythonを使ってWordpressに自動投稿 」、「メディアファイルをWordpressに投稿」を行うためにWP REST APIの準備とPythonコードを紹介しました。
本記事ではいよいよ「 WordPressに画像つき記事を投稿 」する方法をコード付きで紹介したいと思います。なお、本記事は今まで紹介してきた「REST API」を用いて記事の下書きの投稿、複数メディアファイルのuploadができるようになった段階を想定しておりますので、まだの方は上記記事をまずは参照ください。
はじめに
WordPressで[資産運用の週次報告]のページのように実用的な自動投稿を実現するため本記事を含めて5つのステップに分けて解説していきます。
- PythonとWordPressを連携して記事の下書き投稿する
- PythonでWordPressに画像を追加
- PythonでWordPressに複数の画像を一括で追加
- PythonとJinja2でWordPress投稿記事を編集 (本文・画像追加・ギャラリー) (本記事)
- REST APIでHTML文とアイキャッチ画像を設定して投稿する
各ステップの流れを一つの流れに整理すると以下のフロー図で示すことができ、本記事で紹介する範囲は黄色ハイライトした箇所です。複数の記事にまたがるとどの内容を見ているかを見失ってしまいやすいので、適宜このフローチャートを確認してください。
◆ Mac OS
◆ Python 3
◆ JupyterLab
◆ WordPress ver. 5.8
WordPressに画像つきの記事 (本文中埋め込み・アイキャッチ)を投稿するには
先に紹介した関連記事を読み終わった人は「WP REST API」の設定も終わり、メディアファイルも複数uploadできているかと思います。具体的な想定読者は、以下の悩みを持つ人たちです。
メディアファイルを記事内に入れるにはHTMLをいじればいいのだろうけど、どうやってHTMLを編集したら画像の埋め込み、ギャラリーやアイキャッチ画像を設定できるのだろう。
HTML中にPythonで作成したlistの値や変数を入れたいのだけど、どうすればPythonとHTMLと連携できるのだろうか。
上記の悩みを解決するには、1) WordPressの本文記事のHTML, アイキャッチ画像の投稿方法を理解して、2) HTMLとPythonの連携にテンプレートライブラリのJinja2を使用しましょう!
WordPressの本文記事のHTMLを理解する
まずWordpressの記事を投稿する際にどのようなHTMLの記述がされているのかを確認します。投稿記事編集画面の右上の「テキスト」をクリックするとHTMLが確認できます。
そうすると「埋め込み画像」と「ギャラリー」で異なる記述がされているのに気づきます。
本文中の埋め込み画像
埋め込み画像は<img=class=...>
で記載された箇所であることがわかります。さらによく見るとHTML中のsrc=
にこちらの記事で紹介したmedia_url
を指定することで本文中に表示されることがわかります。
1 2 |
記事中の埋め込み画像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_url (src中のURL)をよく見るとメディアファイルごとに共通のパートがあることがわかります。
src=”https://life100create.com/wp-content/uploads/2022/07/test.png”
黄マーク部:サイト固有の部分
青マーク部:メディアファイルをuploadした日付由来の部分
赤マーク部:メディアファイル名
このHTMLファイルをテンプレート化する場合には、青マーク部と赤マーク部を上手にPython (Jinja2)で処理してあげれば上手くいきます。
ギャラリー
HTML中のgallery ids=
の後の数字を変えるとギャラリーとして表示される画像が変更されます。これはこちらの記事で紹介したmedia_id
を指定することで本文中に反映されます。
1 2 |
ギャラリーHTML: gallery ids="1,2,3" |
media idはWordpressのメディア一覧からでも以下の手順で確認することができます。
アイキャッチ画像の投稿方法
アイキャッチ画像
このアイキャッチ画像はWordpressのテキスト本文中には表示されませんが、REST APIで投稿時にmedia_id
を指定することで設定されます。その指定は以下のコード例でいうと9行目のfeatured_media
の部分です。
1 2 3 4 5 6 7 8 9 10 |
# 投稿設定: 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 } |
1 2 3 4 |
import pandas as pd media_info_df = pd.DataFrame(media_info_list) media_info_df.to_csv('media_info.csv',header=False, index=False) |
Jinja2を用いてHTMLテンプレートの作成
上記まででWordpress中のメディアファイルと「media_url」「media_id」の記述方法について述べてきました。ここから具体的にWordpressの投稿記事本文の準備の説明をしていきます。
REST APIを用いてWordpressに自動投稿する際には、以下コードの「post」の「content」で本文記事の内容を記載します。
1 2 3 4 5 6 7 8 9 10 |
# 投稿設定: 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 } |
そのため例えばcontentを以下のように記載すれば記事の投稿は行えます。しかしこれだといちいち「media_url」や「media_id」を確認してcontentの内容を更新する必要があり自動化できたとは言えません。そこで、こちらの記事の「メディアIDなどのmedia infoを整理する」で紹介したlistから「media_url」や「media_id」の情報を読み込んでcontentを更新するコードを用意します。
この時に重要となるのが、「Jinja2」です。
Jinja2 とは
Jinja2とは、「python用の、html作成時に使用できるテンプレートエンジン」です。Jinja2の一般的な説明や使用方法についてはこちらの記事を参照してもらい本記事中での詳細な説明は割愛します。
Jinja2でHTML用テキスト作成
以下はJinja2の仕組みを示すための簡易的な例です。
一般的にjinjaを使用する際には、以下の3つに構成を分けることが主流です。
- template (htmlのテンプレート)
- parameter (テンプレート中に挿入したいパラメータ)
- rendering (jinjaを実行)
Jinja2の記載方法の最大の特徴は、template中の {{ … }} (波かっこ)を用いた記法です。この{{ … }}中の文字をparameter中で設定したkey文字列とすことでPython実行時にkey文字列と対応するvalueがtemplate中に出力されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# jinja2未Install時のみ実行 # !pip install jinja2 # 簡易版検討 from jinja2 import Template date = '202207' # メディアファイルをアップした日付 tpl_html = ''' <!-- wp:paragraph --> <p>Jinja2でテンプレートHTMLにPythonで値を入れ込みます。</p> <h2>本文中の埋め込み画像</h2> <p><img class="aligncenter size-full " src="https://life100create.com/wp-content/uploads/{{ yyyy }}/{{ mm }}/test.png" alt="" width="650" height="450" /> <h2>ギャラリー</h2> <p>【gallery ids="{{ gal01 }},{{ gal02 }},{{ gal03 }}"】</p> ←【 】 を [ ]に置き換えてください。 ''' template = Template(tpl_html) # date='202207'の場合、以下のparameterは {'yyyy': '2022', 'mm': '07'} parameter = {'yyyy': date[:4], 'mm': date[4:6], 'gal01': 1, 'gal02': 2, 'gal03': 3} rend_html = template.render(parameter) # 辞書で指定する print(rend_html) |
Wordpress中に投稿する関係でgallery ids=を[ ]で囲えなかったため、Pythonのコード中で【 】 を [ ]に置き換えてください。
実行結果
1 2 3 4 5 6 7 8 |
<!-- wp:paragraph --> <p>Jinja2でテンプレートHTMLにPythonで値を入れ込みます。</p> <h2>本文中の埋め込み画像</h2> <p><img class="aligncenter size-full " src="https://life100create.com/wp-content/uploads/2022/07/test.png" alt="" width="650" height="450" /> <h2>ギャラリー</h2> <p>【gallery ids="1,2,3"】</p> |
今回のHTML中で、「本文中の埋め込み画像」を表示するsrc = urlですが、今回はuploadした日付に応じてURLの一部を変更するように処理をしておりますが、先に取得した「media_url」を対応させることでも対応可能です。「media_url」は自分でファイル名を決められるのである程度パターン化しやすくJinja2でテンプレート処理しやすいです。
一方ギャラリー(とこの後に説明するアイキャッチ画像)に使用する「media_id」は、WordpressにUploadされたら連番となるように自動的に採番されるためJinja2でテンプレート処理をする際にちょっとしたコツが必要です。
私は、「media_info_list」からpandas dataframeを作成して、そのdataframeで何番目かと整理して「media_id」を取得しています。なぜなら、ファイル名や作成する画像の種類が変更にならない限り、ファイル名の順番は変更なしのため、media_id自体の番号がuploadされるたびに変わっても「上から何番目のファイルか」という情報のみでmedia_idを取得できます。
1 2 3 |
import pandas as pd media_info_df = pd.read_csv('media_info.csv') media_info_df |
実行結果
実行すると以下のような形でdataframeが得られるかと思います。なお、dfの中身自体はuploadされたファイル名などによって異なります。
filename | filepath | media_id | ||
---|---|---|---|---|
0 | 20220713_xxx.png | /Users/mark/xxx/20220713_xxx.png | 1 | |
1 | 20220713_yyy.png | /Users/mark/xxx/20220713_yyy.png | 2 | |
2 | 20220713_zzz.png | /Users/mark/xxx/20220713_zzz.png | 3 |
このdfから「media_id」を取り出すには.iloc
を使用します。この.iloc
はdataframeの[何行目、何列]かを指定することで得られます。
1 2 3 4 5 6 |
# media_idの表示例 media_info_df.iloc[0,2] #> 1 media_info_df.iloc[1,2] #> 2 |
したがって上記のdataframeでの表示に先のJinja2のギャラリー用のmedia_idのコードを修正すると以下のようになります。
1 2 3 4 5 |
parameter = {'yyyy': date[:4], 'mm': date[4:6], 'gal01': media_info_df.iloc[0,2], 'gal02': media_info_df.iloc[1,2], 'gal03': media_info_df.iloc[2,2]} |
これで、Jinja2を用いて自動投稿用のテキストをPythonの出力を組み込んで作成することができました。あとはこれをREST APIのcreate_postコードのpost部分に関連づければOKです。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# rendered HTMLの設定 content = rend_html # 投稿設定: 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 } |
次のステップに向けて
今回は「PythonでWordPress投稿記事を編集 (本文・画像追加・ギャラリー画像の設定)」を実行するための「pythonのコード」を紹介しました。
WordPressで[資産運用の週次報告]のページのように実用的な自動投稿を実現するためのステップは以下の通りです。
- PythonとWordPressを連携して記事の下書き投稿する
- PythonでWordPressに画像を追加
- PythonでWordPressに複数の画像を一括で追加
- PythonとJinja2でWordPress投稿記事を編集 (本文・画像追加・ギャラリー) (本記事)
- REST APIでHTML文とアイキャッチ画像を設定して投稿する
次回はいよいよ最後、「REST APIでHTML文とアイキャッチ画像を設定して投稿」する方法について紹介したいと思います。
コメント