| name | note-export-import |
| description | note.com の公式エクスポート(WXR ZIP)取り込み・インポート用WXR生成・articles_note/ の再編成を扱うワークフロー。ZIPの日時別アーカイブ、published/drafts/assets 再生成、新規MD→単一記事WXR変換、note仕様上の制約(インポートは常に新規下書き、タグ・目次・価格は失われる)を統括する。 |
note-export-import
note.com 記事のローカル管理 (articles_note/) のエクスポート取り込み と インポート用WXR生成 を扱うスキル。
トリガー
- ユーザーが「note公式エクスポートを取り込みたい/反映したい」と依頼したとき
- ユーザーが「新規記事をnoteにインポートしたい/下書きにしたい」と依頼したとき
note-export-importer エージェントから参照
articles_note/export/ 配下の新しいZIPを取り込む必要があるとき
前提ディレクトリ構成
articles_note/
├── README.md
├── assets/ 画像(実体)、Markdownから ../assets/... で参照
├── export/
│ └── YYYY-MM-DD/*.zip 公式エクスポートZIP原本(日時別バックアップ)
├── published/ note公開中 (.md)
├── drafts/ note下書き (.md)
├── new/ 未投稿の新規原稿 (.md)
└── build/ インポート用WXR出力 (.gitignore推奨)
note仕様上の重要な制約(必ず意識する)
- インポートは常に新規下書きを作成する。既存記事を上書きする機能はない
- GUID/URL一致でも更新されない
- 既存記事の更新は「note上で直接編集」が基本。差し替えコピペで実現
- インポート対応形式: WXR (.xml) または MT (.txt)
- 上限: 1回 20MB / 1,000記事
- 取り込み可否:
- ○ タイトル / 本文 /
<img src="https://..."> の画像(noteに再保存される)
- × 目次 / ハッシュタグ / 価格 / 試し読みライン / 一部の埋め込み・装飾
- 成功/失敗は 3日以内にメール通知
- インポート後の記事はすべて「下書き」として追加される
ワークフロー
A. エクスポート取り込み(バックアップ更新)
- ZIPパスを特定(例:
articles_note/export/2026-04-16/xxx.zip または ~/Downloads/...zip)
- 展開先ディレクトリを一時作成 → ZIPを解凍
- ZIPを
articles_note/export/YYYY-MM-DD/ にリネームせずに配置(まだの場合)
- WXR (
note-*.xml) + assets/ を取得
scripts/wxr_to_md.py で published/ drafts/ を再生成
- ⚠️ 取り込みは
published/ drafts/ を server 状態で上書き再生成する。これらに未コミットのローカル編集があると巻き戻る(2026-04-26 で 2 記事巻き戻り事故)。スクリプトは取り込み前に git status --short で dirty を検出し、未コミット変更があれば exit 1 で停止する。先に commit/stash するか、編集が new/ にあるべきか確認すること。意図して上書きする場合のみ --force
assets/ は最新エクスポート内容で上書き(ルートの articles_note/assets/)
- 差分をレビューしてコミット
B. 新規記事インポート(下書き作成)
new/<slug>.md を用意(著者が執筆)
- 記事に SVG 画像がある場合: 先に Chrome headless で PNG 変換し
articles_note/assets/ に配置する(上記「SVG→PNG 変換」参照)
scripts/md_to_wxr.py new/<slug>.md --base-url <公開Raw URL> で build/import-<slug>-YYYYMMDD-HHMM.xml を生成
scripts/verify_wxr.py build/import-*.xml で構造検証(必須 wp:* の欠落と著者フィールドの対応を公式エクスポートと突き合わせ)
- note管理画面: プロフィール → 自分の記事 → インポート → WXR選択
build/import-<slug>-YYYYMMDD-HHMM.xml をアップロード → インポート開始
- 3日以内にメール通知 → 下書きが作成される
- noteエディタで画像差し替え・最終調整 → 公開
- 公開後は次回バックアップ取り込みで
published/ に反映される
注意: xmllint --noout でwell-formedでも note importer が弾くことがある(<item> の wp:* 欠落など)。必ず verify_wxr.py を通す(2026-04-18 にこの罠で実インポート失敗)。
C. 既存記事更新(上書き不可の回避)
- 推奨: A方式 —
published/<slug>.md を参照しつつ note上で直接編集
- B方式 — B手順で新下書きを作り、note上で既存記事の本文に上書きコピペ
- C方式(非推奨) — 旧記事削除 + 新規インポート。URL/スキ/コメントが失われる
画像の扱い
- ローカル画像 (
../assets/foo.png) は note にインポートされない
- 自動取り込みは
<img src="https://..."> (JPEG/PNG/GIF) のみ。SVG は非対応
- WXR 内の画像タグは
<figure name="uuid"><img src="..."><figcaption></figcaption></figure> 形式が必須。<p><img /></p> では note インポーターに無視される(md_to_wxr.py が自動変換)
- 対応:
- a) 画像をGitHub Raw等でhttps配信 →
md_to_wxr.py --base-url <raw-url> で絶対URLへ書き換え
- b) インポート後 note エディタで手動貼り直し(実用的)
SVG→PNG 変換(日本語テキストを含む場合)
macOS では cairosvg は日本語フォントを正常レンダリングできない(Hiragino/.ttc 未解決 → □□□)。
Chrome headless を使うこと。さらに SVG の font-family が未指定/汎用名のままだと Chrome でも豆腐になり得るため、レンダリング前に SVG 内の全 font-family を明示的に Hiragino へ正規表現置換してから渡す:
python3 - <<'PY'
import re
s=open('in.svg',encoding='utf-8').read()
JP='Hiragino Sans, Hiragino Kaku Gothic ProN, sans-serif'
if 'font-family' not in s.split('>')[0]:
s=s.replace('<svg ', f'<svg font-family="{JP}" ',1)
s=re.sub(r'font-family\s*=\s*"[^"]*"', f'font-family="{JP}"', s)
s=re.sub(r'font-family\s*:\s*[^;"]+', f'font-family:{JP}', s)
open('out.svg','w',encoding='utf-8').write(s)
PY
置換済み SVG を HTML でラップし(<body> 直下に貼る)、--force-device-scale-factor=2 と viewBox 比率に合わせた --window-size で Chrome headless に渡す。生成後は必ず目視で tofu / 見切れ / 文言を確認する(Gemini 設計の図・カバーは AGENT_LEARNINGS.md 2026-05-15 参照)。
基本形は以下:
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
--headless=new \
--screenshot="articles_note/assets/output.png" \
--window-size=1200,630 \
--hide-scrollbars \
"file:///$(pwd)/articles_note/new/images/input.svg" 2>/dev/null
複数ファイルを一括変換する例:
for svg in foo bar baz; do
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
--headless=new --screenshot="articles_note/assets/${svg}.png" \
--window-size=1200,630 --hide-scrollbars \
"file:///$(pwd)/articles_note/new/images/${svg}.svg" 2>/dev/null
done
変換後は PNG が articles_note/assets/ に配置されていること・ファイルサイズが妥当(>50KB)であることを確認してから WXR を生成する。
スクリプト
scripts/wxr_to_md.py — WXR + assets → published/ drafts/ assets/ を再生成
scripts/md_to_wxr.py — new/<slug>.md → 単一記事WXR を build/import-<slug>-YYYYMMDD-HHMM.xml に出力
scripts/verify_wxr.py — 生成WXRを公式エクスポート形式と突き合わせ、note importerが必要な <item> 配下 wp:* の欠落や著者フィールドの対応違いを検出
wxr_to_md.py / md_to_wxr.py は pip install --break-system-packages markdownify markdown が必要。verify_wxr.py は標準ライブラリのみ。
区分メタの扱い(任意)
各MDのヘッダーに区分タグを入れる運用も可能:
> 区分: 公式ブログ / > 区分: 個人
- 自動判定ヒント:
- 個人: 「個人の活動による」「会社の公式見解では」等の免責あり
- 公式寄り: 上記免責なし かつ「ユニラボ」「PRONI」「アイミツ」等の社名言及あり
エージェント連携
note-export-importer — A/B/C ワークフローを対話的に実行
関連リンク