今回はこれまで作成したWordPress REST APIを使ったクラスを使用して、画像入りのブログ記事原稿を投稿する関数を作成します。
これまでの記事はこちら
前提
- WordPressのREST APIを使った投稿や画像アップロードを行うクラスはできている
- ブログ記事の原稿として、マークダウンからHTMLに変換する部分はできている
マークダウンをHTMLに変換する方法については以下で紹介しています。
マークダウンをHTMLに変換する基本的な方法
拡張機能を使って、より複雑な記法にも対応する方法
今回は、投稿用のhtmlはできている前提で、そのHTMLから画像部分を抽出して、WordPress REST APIで画像をアップロードしつつ、最終的な記事をアップロードする機能を実装します。
コード
from bs4 import BeautifulSoup
def html_img(wp_client, html,img_folder,upload_type=1 ):
# Beautiful SoupでHTMLを解析
soup = BeautifulSoup(html, 'html.parser')
media_ids = []
for img_tag in soup.find_all('img'):
# imgタグの親要素が<pre>または<code>タグでない場合にのみ処理を行う
if img_tag.find_parent(['pre', 'code']) is None:
if img_tag.get('src')[:4]!='http':
img_file = os.path.basename(img_tag['src'])
img_path = os.path.join(img_folder, img_file)
media_id = wp_client.upload_image_type(img_path, upload_type=upload_type)
if media_id is not None:
media_ids.append(media_id)
meta_data = wp_client.get_media_by_id(media_id)
sizes = meta_data.get('media_details', {}).get('sizes',{})
if 'large' in sizes.keys():
img_tag['src'] = sizes['large']['source_url']
else:
img_tag['src'] = meta_data['source_url']
img_tag['class'] = f'wp-image-{media_id}'
else:
raise ValueError
return str(soup), media_ids
実行するには以下のように書きます。
# 必要な情報を定義
wp_url = "https://your-wordpress-site.com"
auth_method = "jwt"
auth_info = {
"token": "your_jwt_token" # 事前に取得したJWTトークン
}
# WordPressClientのインスタンスを作成
wp_client = WordPressClient(wp_url, auth_method, auth_info)
html = '投稿用のHTML'
img_folder = '画像が保存されているフォルダーへの絶対パス'
html_img(wp_client, html,img_folder)
このコードは、HTMLから画像を抽出し、WordPressにアップロードして、HTML内の画像リンクを更新するPython関数 html_img
を実装したものです。次に、コードの各部分を詳しく解説します。
使用するライブラリ
- BeautifulSoup: HTMLやXMLファイルを解析して操作するためのPythonライブラリです。このコードでは、HTMLのパースと画像タグの抽出に使用されています。
関数 html_img の説明
def html_img(wp_client, html, img_folder, upload_type=1):
この関数は、以下の引数を取ります:
wp_client
: WordPressのAPIクライアント。画像のアップロードとメタデータの取得に使用されます。html
: 画像タグを含むHTML文字列。img_folder
: ローカル画像フォルダのパス。HTML内で参照される画像ファイルがここに存在する必要があります。upload_type
(デフォルト値:1
): 画像のアップロードタイプを指定するための引数。詳細はwp_client.upload_image_type
メソッドに依存します。
HTMLの解析
soup = BeautifulSoup(html, 'html.parser')
media_ids = []
BeautifulSoup
クラスを使って、渡されたHTML文字列html
を解析します。この解析結果をsoup
というオブジェクトに格納します。media_ids
は、アップロードされた画像のメディアIDを格納するリストです。
画像タグ(<img>)の抽出と処理
for img_tag in soup.find_all('img'):
soup.find_all('img')
で全ての<img>
タグを取得し、ループで処理します。
画像タグの親要素が <pre> または <code> でないか確認
if img_tag.find_parent(['pre', 'code']) is None:
- 画像タグの親要素が
<pre>
または<code>
タグでない場合のみ処理を行います。コードスニペットなどの中に含まれる画像はアップロードしないためのチェックです。
画像の相対パスを絶対パスに変換してアップロード
if img_tag.get('src')[:4] != 'http':
img_file = os.path.basename(img_tag['src'])
img_path = os.path.join(img_folder, img_file)
media_id = wp_client.upload_image_type(img_path, upload_type=upload_type)
img_tag.get('src')[:4] != 'http'
で、画像のsrc
属性が相対パスであるかをチェックします。os.path.basename(img_tag['src'])
で、src
属性からファイル名を取得し、img_folder
パスと組み合わせて画像のフルパスを作成します。wp_client.upload_image_type(img_path, upload_type=upload_type)
を使って画像をWordPressにアップロードし、その結果としてメディアIDを取得します。
画像アップロード後の処理
if media_id is not None:
media_ids.append(media_id)
meta_data = wp_client.get_media_by_id(media_id).get('media_details', {})
sizes = meta_data.get('sizes', {})
if 'large' in sizes.keys():
img_tag['src'] = sizes['large']['source_url']
else:
img_tag['src'] = meta_data['source_url']
img_tag['class'] = f'wp-image-{media_id}'
else:
raise ValueError
- 画像が正常にアップロードされた場合、
media_ids
リストにメディアIDを追加します。 - アップロードされた画像のメタデータを取得し、
sizes
オブジェクトから画像のサイズ情報を抽出します。 - 画像の新しいファイル名を取得し、HTMLの
src
属性をWordPressの画像URLに置き換えます。 - 画像タグに
class
属性を追加し、WordPressスタイルに合わせます。
更新されたHTMLとメディアIDのリストを返す
return str(soup), media_ids
- すべての画像処理が完了した後、
BeautifulSoup
オブジェクトを文字列に変換して、更新されたHTMLとメディアIDのリストを返します。
まとめ
これでHTMLに画像が含まれる場合にも、投稿が可能になります。