【詳解】アイキャッチ画像を反映するためにWordPressのテーブルを知ろう。

もしもあなたがWordPressにアイキャッチ画像をアップロードするなら、投稿の編集画面から設定するべきだ。手間なく最も簡単にアップロードできるからだ。

しかし、クローラーで取得した画像を半自動的に反映したいのなら、話は別だ。WordPressのテーブルの仕組みは独特で、各テーブルの紐付け方を知らなければならないのである。

そこで今回は、アイキャッチ画像として反映させるために必要な、WordPressのテーブルを説明する。各投稿に紐づく形でアイキャッチ画像を設定することが目的だ。

# 今回の記事の前提
まずは今回の記事の経緯を説明しよう。

9月に再リリースした[リゾートバイト求人検索サイト「RESORN（リゾーン）」](https://resorn.net/)では、Python3でクローラーを回し、求人情報を取得している。

しかし、時間的なリソースの関係で画像を取得できていない現状があり、解決する必要があった。当時、抱えていた状況は以下のようなものだ。

1. すでに各投稿は用意されている。
2. 画像はサーバーのディレクトリに未保存である。
3. Python3で画像を格納したい。
4. アイキャッチ画像は未設定である。

つまり、「投稿はあるが、画像は未取得」という状況があった訳だ。したがって、以上の状況を前提として話を進めていきたい。

# 今回の狙い・目的・前提
1. ディレクトリへの保存場所を知る。
2. 保存した画像を各投稿と紐付ける。
3. 保存した画像はアイキャッチ画像に位置付ける。

# ステップ①：画像をディレクトリに保存する
画像は通常、以下の形でWordPressが置かれたサーバーに保存される。

`<ドメイン>/wp-content/uploads/2018/11/photo.jpg`

注目すべきは、/uploads/以下のディレクトリで、アップロードした画像は年月ごとに格納される仕組みになっている。確かに、この仕組みはアップロード年月ごとに画像を分類できるメリットがある。しかし、Pythonでの画像保存を考えると処理が難しくなりがちで、年月を分ける大きなメリットは存在しない。

そこで、/uploads/直下に新たにディレクトリを作り、そこに格納することを考えよう。

`<ドメイン>/wp-content/uploads/scraping-image/`

Pythonでスクレイピングした画像を保存する場合は、以下の4つのライブラリが検討できる（今回はBeautifulSoupを使用した）。

- urllibを使う方法
- BeautifulSoupを使う方法
- OpenCVを使う方法
- Numpyを使う方法

# ステップ②：保存した画像を各投稿と紐づける
アイキャッチ画像と投稿を紐付けるには、WordPressで画像が反映される仕組みを知らなければならない。

幸運にも、画像情報が格納されるテーブルはたったの2つだけだ。

- **①"wp_posts"テーブル**：投稿・画像の基本情報を格納。
- **②"wp_postmeta"テーブル**：投稿・画像に紐づく各種情報を格納。

問題は、"wp_postmeta"テーブルに

①の"wp_posts"テーブルには、画像パス(URI)に紐づけてID、ファイル名、アップロード時間などの情報が記録される。

②の"wp_postmeta"テーブルには「画像がアイキャッチ画像であることを示すデータ」「画像の格納場所を示すデータ」「画像のシリアライズデータ」の3つの情報が記録される。

参考：[wordpressで画像はどのようにデータベースに記録されているか](https://unskilled.site/wordpress%E3%81%A7%E7%94%BB%E5%83%8F%E3%81%AF%E3%81%A9%E3%81%AE%E3%82%88%E3%81%86%E3%81%AB%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%81%AB%E8%A8%98%E9%8C%B2%E3%81%95%E3%82%8C%E3%81%A6/)

以上を元に、WordPressにおけるアイキャッチ画像の保存・反映に関して情報をまとめると、以下の5つが考慮すべきデータとなる。

* **①投稿のデータ**
    * 使用テーブル："wp_posts"
    * post_type列：post
* **②画像の基本情報と親投稿（①）のデータ**
    * 使用テーブル："wp_posts"
    * post_type列：attachment
* **③画像がアイキャッチ画像であることを示すデータ**
    * 使用テーブル："wp_postmeta"
    * meta_key列：\_thumbnail_id
* **④画像の格納場所を示すデータ**
    * 使用テーブル："wp_postmeta"
    * meta_key列：\_wp_attached_file
* **⑤画像のシリアライズデータ**
    * 使用テーブル："wp_postmeta"
    * meta_key列：\_wp_attachment_metadata

つまり、①の投稿、②の画像情報に紐づける形で、③④⑤を書き込むことを考えれば良い訳だ。投稿情報にあたる①は「すでに格納されている」という前提のため、②～⑤に絞って話を進めていこう。

# ステップ③：具体的なテーブルの中身を知る
それでは実際に、各テーブル・データの中身を見てみよう。

## ②画像の基本情報と親投稿（①）のデータ

| パラメータ      |  意味       |    値の例    |
|:-----------------|:------------------|:------------------|
| ID            |              ID |        810        |
| post_author           |          投稿者 |       1       |
| post_date             | 画像をアップロードした日時 |1999-07-31 12:07:45|
| post_date_gmt    |  画像をアップロードした日時 | 1999-07-31 3:07:45|
| post_content| 本文(画像の場合は空白)|             |
| post_title| 画像のファイル名|114514|
| post_excerpt|抜粋文(画像の場合は空白)|     |
| post_status|画像の状態|inherit(publishでも可)|
| comment_status| コメントの状態| open|
| ping_status| ping送信 |  open |
| post_password  |  パスワード|             |
| post_name|     画像のファイル名 |  114514  |
| to_ping   |   ping送信先 |      |
| pinged    |   ピンバックした履歴 |       |
| post_modified   |  更新日時 |    2020-02-10 12:07:45   |
| post_modified_gmt |  GMTでの更新日時 |  2020-02-10 3:07   |
| post_content_filtered   |    不要 |             |
| post_parent |親投稿(画像と紐づける投稿のID)|     334      |
| guid |画像パス(URI)|   <ドメイン名>/wp-content/uploads/scraping-image/114514.jpg        |
|menu_order | 表示順序（不要） | 0 |
| post_type | 投稿の種類 | attachment |
| post_mime_type | 添付ファイルのタイプ | image/jpeg |
| comment_count | コメント数 | 0 |




## ③画像がアイキャッチ画像であることを示すデータ

| meta_id    |  post_id   |  meta_key    | meta_value |
|:-----------------|:------------------|:------------------|:------------------|
|ID| 投稿ID | アイキャッチ画像であることを示すキー | 画像ID |
| 2525 | 334 | \_thumbnail_id | 810 |


## ④画像の格納場所を示すデータ

| meta_id    |  post_id   |  meta_key    | meta_value |
|:-----------------|:------------------|:------------------|:------------------|
|ID| 画像ID | アイキャッチ画像であることを示すキー | /uploads/以下のディレクトリ・ファイル名 |
| 4649 | 334 | \_wp_attached_file | scraping-image/114514.jpg |


## ⑤画像のシリアライズデータ

| meta_id    |  post_id   |  meta_key    | meta_value |
|:-----------------|:------------------|:------------------|:------------------|
|ID| 画像ID | メタデータであることを示すキー | シリアライズデータ |
|31415 | 334 | \_wp_attachment_metadata | a:5:{s:5:"width";i:500;s:6:"height"... |


注意点は、"wp_postmeta"テーブルのpost_idの紐付き方である。

たとえば、④はpost_idが"wp_posts"テーブルの「投稿ID」に結びついているのに対し、⑤⑥は「画像ID」と関連している。だから、紐付けるIDを間違えないように注意しなければならないのだ。

なお、実際の実装では、「⑤画像のシリアライズデータ」を反映せずにアイキャッチ画像を設定できた。