WordPress の WXR エクスポートに画像は含まれない — 移行で画像が消える理由と、消えた後の復元
WordPress からの移行後、記事内の画像が数十件単位で 404 になっているサイトを 2 つ抱えていました。原因を遡ると行き着いたのは、WordPress 移行の最も誤解されやすい仕様です。エクスポート機能が吐き出す WXR ファイルには、画像そのものは 1 バイトも含まれていません。
旧サーバーがまだ生きていれば取り返しがつきます。しかし解約済みなら、画像の原本はこの世から消えています。私はこの状態から Wayback Machine(Internet Archive)を使って 36 件の画像を回収しました。この記事は前半が「これから移行する人が事故らないための仕様解説」、後半が「もう手遅れだった人のための復元手順」です。
WXR エクスポートに入っているもの、入っていないもの
WordPress の管理画面「ツール → エクスポート」が生成するのは WXR(WordPress eXtended RSS)という XML ファイルです。中身は次の通りです。
入っているもの
- 投稿・固定ページの本文(HTML)
- カテゴリー・タグ・カスタムタクソノミー
- コメント
- メディアのメタデータ(タイトル、説明、そして元ファイルの URL)
入っていないもの
- 画像・動画・PDF などのファイル本体
つまり WXR が持っているのは「画像がどこにあるか」という住所録だけで、画像そのものは旧サーバーの wp-content/uploads/ に置かれたままです。インポーター側の「添付ファイルをダウンロードしてインポートする」オプションは、この住所録を頼りに旧サイトへ HTTP アクセスして画像を取りに行く機能なので、旧サイトが生きている間しか機能しません。
事故のシナリオ: 「移行完了に見える」が罠
この仕様が事故につながるのは、移行直後はすべて正常に見えるからです。
- WXR をエクスポートして新環境にインポートする。記事は全部入った
- サイトを表示すると画像も表示されている — 記事内の
<img>の URL が旧サーバーを向いたままで、旧サーバーがまだ生きているからです - 「移行完了」と判断して旧サーバーを解約する
- 数週間後、全記事の画像が 404 になっていることに気づく。原本はもうどこにもない
3 の時点で確認したのは「表示されるか」であって「どこから配信されているか」ではない、というのがこの罠の核心です。
これから移行する人へ: 事故らないためのチェックリスト
- `wp-content/uploads/` を丸ごと取得する。FTP/SSH でディレクトリごとダウンロードするのが確実です。WXR とセットで初めて「完全なエクスポート」になります
- 旧サーバーの解約前に、新環境の画像の配信元を確認する。ブラウザの開発者ツールで画像 URL のドメインを見るだけです。旧ドメイン・旧サーバーを向いていたら移行は終わっていません
- 移行ツールを使う場合も、画像が含まれる方式か確認する。関連して「All-in-One WP Migrationでインポートに失敗する」も参考になるはずです
- 移行後、旧 URL 形式で来るアクセスは 301 で救う。設計は「WordPress 移行後に記事内の画像が 404 になる — /wp-content/uploads/ を動的ルート 1 本で旧 URL のまま救う」に書きました
手遅れだった人へ: Wayback Machine から復元する
ここからが後半です。原本が消えていても、Internet Archive(archive.org)のクローラーが生前のサイトを巡回していれば、画像のコピーがアーカイブに残っています。Wayback Machine は世界中のウェブページを定期的に保存している非営利のアーカイブサービスで、HTML だけでなく画像などのファイルも保存されています。
基本の取得方法
まず、その URL のスナップショットがあるか確認します。
curl "http://archive.org/wayback/available?url=example.com/wp-content/uploads/2018/02/photo.jpg"スナップショットが見つかったら、タイムスタンプの後ろに `im_` フラグを付けて取得します。これが重要で、im_ を付けると Wayback のツールバーなどが注入されていないオリジナルのバイナリそのものが返ります。
curl -L -o photo.jpg \
"https://web.archive.org/web/20230101000000im_/https://example.com/wp-content/uploads/2018/02/photo.jpg"全キャプチャの一覧が欲しい場合は CDX API を使います。
curl "https://web.archive.org/cdx/search/cdx?url=example.com/wp-content/uploads/2018/02/photo.jpg&output=json"実務でハマった落とし穴
36 件の回収作業で踏んだ落とし穴を共有します。
- 「200 のキャプチャ」が空ファイルのことがある。CDX の結果に digest 列があり、
3I42H3S6NNFQ2MSVX7XZKYAYSCX5QBYJは空コンテンツの SHA-1 ダイジェストです。この値のキャプチャはダウンロードしても 0 バイトなので、取得前に弾けます - ファイル名の拡張子と中身が一致しないことがある。WordPress はサイトアイコン機能で JPEG を `favicon.ico` という名前のまま配信したりします。回収したファイルは拡張子を信用せず、マジックバイトで中身を検査してください(
ff d8 ffなら JPEG、89 50 4e 47なら PNG) - 原寸がなく `-300x200` のようなサムネイル版しか残っていないことがある。WordPress は画像を複数サイズで生成するため、クローラーが拾ったのがサムネイル版だけというケースです。記事表示用ならサムネイル版でも十分なことが多いので、原寸が見つからなければサイズ違いを探します
- 他サイトからのホットリンクだった画像は、そのサイト側に原本がある。私のケースでは片方のサイトの装飾画像 8 枚が、実は姉妹サイトからの直リンクでした。404 の URL を機械的に archive.org へ問い合わせる前に、原本の所在を一度考える価値があります
回収できなかった画像は最終的に 1 枚だけで、その画像は記事から画像ブロックごと外す判断をしました。全部は戻らない前提で、戻らなかったものをどうするかまで決めるのが復元作業です。
復元していいのは「自分が権利を持つもの」だけ
この手法は強力なので、線引きを明確にしておきます。
法的な観点 — 判断軸は「そのファイルの著作権者は誰か」で、Wayback はただの経由地です。自分のサイトの自分の著作物なら、著作権者本人が自分の作品のコピーを取り戻しているだけで、問題はありません。一方、他人のサイトのコンテンツを Wayback から取得して自分のサイトで再公開するのは、通常の無断転載と同じです。閉鎖したサイトでも著作権は消えていません。また、記事内に有料ストックフォトなど第三者のライセンス素材が含まれていた場合、ライセンスの証明を失っていると立場が弱くなる点にも注意が必要です。制作会社が顧客の依頼で顧客のサイトを復元するのは、権利者の許諾があるので問題ありません。
マナーの観点 — Internet Archive は寄付で運営されている非営利団体です。数十ファイル程度の取得は日常的な利用の範囲ですが、リクエストは逐次・間隔を空けて行い、サイト丸ごとを並列で叩くようなことは避けるべきです。そもそも彼らが保存していなければ復元は不可能だったわけで、本格的に世話になったなら寄付という形でお返しする選択肢もあります。
まとめ
- WXR エクスポートに画像のバイナリは含まれない。含まれるのはメタデータと URL だけで、インポーターの画像取得は旧サイトが生きている間しか機能しない
- 移行直後は記事内の画像 URL が旧サーバーを向いたまま表示されるため「移行完了に見える」。配信元を確認せずに旧サーバーを解約すると原本が消える
- 事前対策は
wp-content/uploads/の丸ごと取得と、解約前の配信元確認 - 手遅れなら Wayback Machine から回収できる可能性がある。
im_フラグでオリジナルバイナリを取得、CDX API でキャプチャ一覧、空キャプチャは digest3I42H3...で判別 - 拡張子と中身の不一致、サムネイル版しか残っていないケース、ホットリンクに注意。全部は戻らない前提で臨む
- 復元していいのは自分が権利を持つものだけ。他人のコンテンツの取得・再公開は無断転載と同じ。Internet Archive には負荷をかけない