Economistの韓国DRAMチャートを再現しようとした話
The Economist の Graphic detail(May 15th 2025)に「Korean DRAM prices hit another record high」というチャートがあった。Surging demand for AI memory drives 18% jump in just ten days というサブタイトルで、韓国の DRAM 輸出単価( per kg, 月次)が 2020-05〜2025-05 でほぼ水平に推移していたものが、2025年に入って急騰し、2025年5月に **64,000/kg** に達したという内容。出所は Korea Customs Service と書いてあった。
このチャートを Vue ページとして自分のサイトに作りたい。元データを取りに行ってみたら、想定の3倍くらい紆余曲折があった上に、最後まで Economist の数字とは完全一致できなかった。その経緯をそのまま残しておく。
完成したチャートはこちら → /blog/korea-dram-export-prices
出発点:UN Comtrade Public API
最初は UN Comtrade の Public API を試した。理由は3つ:
- API キー無しで叩ける
- HS コード単位(6桁)で月次データが世界中の国について取れる
- 韓国の reporterCode = 410、DRAM の HS6桁 = 854232 で一発
curl "https://comtradeapi.un.org/public/v1/preview/C/M/HS?reporterCode=410&period=202405&cmdCode=854232&flowCode=X&partnerCode=0&maxRecords=10"
これで月次の primaryValue(FOB値、USD)と netWgt(kg)が返ってくる。unitPriceUsdPerKg = primaryValue / netWgt で単価計算。2020-01〜2024-12 の60ヶ月をまとめて取れた。
ところが、計算結果を見て手が止まった。
| 月 | UN Comtrade 単価 | Economist グラフ |
|---|---|---|
| 2020-05 | $22,964/kg | だいたい $10,000 |
| 2024-05 | $22,109/kg | だいたい $20,000 |
2024-05 はだいたい合うが、2020-05 で 5,000〜10,000 ベースラインがズレる。HS 6桁(854232 = memory IC)には DRAM 以外(SRAM、フラッシュ、ロジック付き memory 等)が混入しているせいだと判明。Economist は Korea Customs Service の HS10桁 で「DRAM だけ」を抜いている。
そして決定的な問題:UN Comtrade は 2025年のデータがまだ未収載(2026-05時点でも)。Economist の記事の主役である 2025年1〜5月の急騰区間が空白。つまり最重要な数字が取れない。
UN Comtrade ルートはここで打ち切り。
KITA k-stat への移行
韓国側の公式ソースに行くしかない。候補:
- 韓国関税庁 unipass(公式)
- KOSIS(韓国統計庁)
- KITA k-stat(韓国貿易協会、無料アクセス可)
WebFetch で unipass と KOSIS は接続失敗(タイムアウト)。SSL証明書周りか相手側のbot対策と思われる。残った k-stat も WebFetch では仕様取得まで。フォームを自動操作してデータを引き出す必要がある。
ここで agent-browser スキル(CLAUDE.mdに書いてある WebFetch の正規フォールバック)を起動した。
agent-browser + Chrome DevTools MCP
戦術はこう決めた:
- ユーザーのChromeを
--remote-debugging-port=9223で起動済みにする - agent-browser を
--cdp 9223で繋ぐ(これでログイン状態を流用) - ページ操作とデータ抽出は Chrome DevTools MCP の
evaluate_script経由で JavaScript を直接走らせる
agent-browser は CDP接続にトラブルがあった(auto-connectが効かないなど)が、Chrome DevTools MCP の方は port 9223 経由で安定して動いた。結局 agent-browser は接続トリガーとして使い、データ抽出は Chrome DevTools MCP に集約する形に落ち着いた。
k-stat の構造を読み解く
k-stat の品목수출입ページ(/stat/kts/pum/ItemImpExpList.screen)に到達。HS単位を「10단위(10桁)」、시작코드を 854232 で絞ると、HS10桁の細分が見えた:
| HSコード | 品목명(韓) | 意味 |
|---|---|---|
| 8542321010 | 디램 | DRAM 単体(chip) |
| 8542321020 | 에스램 | SRAM |
| 8542321030 | 플래시 메모리 | フラッシュメモリ |
| 8542321090 | 기타 | その他(HBM 単体含む可能性) |
| 8542322000 | 하이브리드 집적회로 | Hybrid IC |
| 8542323000 | 복합구조집 집적회로 | Multi-structure IC |
| 8542324000 | 복합부품 집적회로(MCOs) | Multi-Component IC(HBM 等のメモリモジュール) |
「DRAM」と一口に言っても10桁レベルでは 8542321010 と 8542324000(MCOs = HBM のような複合パッケージ)に分かれている。Economist の "Korean DRAM (including modules)" の "modules" が何を指すかが、ここで疑問になる。
ItemImpExpList.screen の制約
このページで月次時系列を取りたかったが、UI 上は 「特定月 vs 前年同月」 の比較しか出ない。s_year=2025, s_month=05 で「2024-05 と 2025-05 の対比表」が返るだけで、12ヶ月分の月次推移は出ない。
しかも8542321010 のセルをクリックしても詳細ポップアップが開かない。表は IBSheet という商用の JavaScript グリッドで、onclick ハンドラが TD ではなく内部の overlay 層に登録されているため、element.click() や dispatchEvent で反応しない。
POST API を直接叩くアプローチも試したが、レスポンスは IBSheet の枠だけで、データ部分は別の Ajax で後から差し込まれる構造。HTML を grep してもデータが出ない。
ここで詰んだので、別ページを探した。
ItemList.screen(맞춤분석)の発見
/stat/cstat/peri/item/ItemList.screen(맞춤분석 / 품목 수출입)に行ったら、UI に 「주기(周期)」 という選択肢があり、년도별 / 분기별 / 월별 を選べる。さらに、시작〜종료で 任意期間を指定できる。
ただし2つの罠:
- 5年制限: 종료日 - 시작日 が 5 年を超えると alert
- 「월별」を選んでも結果は期間集計1行。例えば「2020-01〜2024-12 で 月別」を指定すると、表は「DRAM 全期間集計(5年合計)」が1行返るだけ。月ごとに分解した行は出ない
つまり「月次時系列」は直接取れない。
抜け道:시작 = 종료 = 同じ年同じ月を指定すれば、その1ヶ月だけの集計が返る。これを75回ループすれば月次時系列になる。
75ヶ月ループ取得
実装は Chrome DevTools MCP の evaluate_script で:
const fetchMonth = async (year, month) => {
setSel('e_year', String(year)); // 終了年を先に上げる
setSel('e_month', month); // 終了月も上げる
setSel('s_year', String(year)); // 開始年を合わせる
setSel('s_month', month); // 開始月を合わせる
window.doSearch();
await wait(2200); // IBSheet 再描画待ち
// 8542321010 を含む行から column 5 (수출액) と column 7 (수출중량) を抽出
};
setSel の順序が重要。月を逆方向(2024→2020)に動かすと、「期間 開始 > 終了」で alert が出て検索が走らない。順方向(2020→2026 順次)かつ「終了を先に上げる→開始を合わせる」という順番だと alert なしで通る。
それでも年初(1月)への遷移時には別の race condition があって、最初の 1月だけ「累計値」が混入したので、各年の 01 月は別ルート(s_month を 12→01 に下げる別ロジック)で個別取得した。それでも 2021-01 と 2026-01 だけは k-stat 側のキャッシュ挙動か何かで取れず、最終的には前後月から interpolate した。
結果:DRAM 単体 + MCOs の二系列
DRAM 単体(HS 8542321010)75ヶ月分と、MCOs(HS 8542324000)39ヶ月分(MCOs は HS 改正前の 2020-2022 期間にコードが存在しないので 2023 年から)を取得。Vue + Chart.js で重ね描き。
そこで見えたのは DRAM 単体と MCOs の二極化。
| 月 | DRAM 単体 ($/kg) | MCOs / HBM ($/kg) |
|---|---|---|
| 2024-01 | $10,919 | $36,389 |
| 2024-12 | $15,463 | $39,644 |
| 2025-05 | $14,021 | $36,184 |
| 2025-12 | $23,725 | $54,011 |
| 2026-02 | $48,170 | $87,512 |
| 2026-03 | $55,143 | $64,673 |
DRAM 単体は 2024 年通年 10〜25k 帯で淡々と推移。MCOs(HBM等のメモリモジュール)は 2024 年初から 36k と既にDRAMの3倍水準で、2025-06 から急上昇、2026-02 にピーク $87k。
Economist が言っていた「DRAM (including modules)」の "modules" は、この MCOs (8542324000) のことだと推定が立つ。AI サーバー需要で HBM が高騰している話を、Economist は HS10桁の DRAM single と modules を合算して、あるいは modules 中心に語っていた。
⚠️ Economist の数字との比較:完全一致はしなかった
ここが本記事の核心。
Economist の元グラフでは 2025年5月で **64,000/kg** に達したと書いてある("reaching a record high of 64,000 per kg" "+18% in just ten days")。
ところが、私が k-stat から取得した同月のデータはこれ:
| 系列 | 2025-05 単価 |
|---|---|
| DRAM 単体(HS 8542321010) | $14,021/kg |
| MCOs / HBM(HS 8542324000) | $36,184/kg |
MCOs ですら Economist の半分強。Economist の $64,000/kg を 2025-05 のデータで再現できていない。
私のチャートで 64,673/kg が出るのは **2026-03 の MCOs**。これは Economist の数字「64k」と数値だけ偶然似ているが、時期が1年近くズレている。「再現できた」と言うのは正しくない。
なぜ Economist の数字に届かないか:4つの仮説
完全には特定できていないが、考えられる理由:
- 旬報(10日値)のスパイク: Economist の "+18% in just 10 days, May 1-10 vs April 1-30" は明らかに10日値の話。Korea Customs Service は10日ごとに「잠정」値を出している。月平均にならすと低くなる。私が取った月集計の MCOs
36k と「10日スパイク64k」はそもそも比較対象が違う - 別のHS10桁細分: もしかすると Economist は
8542321090 기타(その他DRAM、HBM単体がここに分類されている可能性)を使っている。今回未取得 - 特定相手国向け集計: Korea から世界全体ではなく、米国向けや特定相手国に絞ると単価が変わる。AI サーバー向けは米国比率が高いので、そこだけ抜くと高くなる
- 数量単位の違い: kg ではなく Unit(個数)基準で計算した可能性。HS10桁データには「수량」列があり、私は kg 列を使ったが Economist は別かもしれない
仮説1(旬報スパイク)が一番ありそう。記事の文章 "+18% in just ten days" がそれを示唆している。
残った謎と次にやること
この記事の段階で確定していること:
- ✅ HS10桁の DRAM single(8542321010)と MCOs(8542324000)を 2020-2026 で月次取得できた
- ✅ Economist の "DRAM (including modules)" の "modules" は MCOs(HBM 等)に相当しそう
- ✅ MCOs の急上昇は 2025-06 以降で、AI サーバー × HBM 需要の話と整合
- ❌ Economist 公開の "$64,000/kg in May 2025" を月次データで再現できていない
次に試したいこと:
8542321090 기타の月次取得(HBM 単体がここに入っていれば $64k に近づくかも)- KITA k-stat の「旬보」(10日値)UI を探す(あれば Economist の数字に直接アクセスできる)
- 米国向けに絞った輸出データ(k-stat の「국가별」タブ、ただし会員社限定機能の m マーク付き)
副産物として記録した工程
データ取得そのものより、Korea Customs Service / KITA k-stat の構造を読み解く工程の方がワークとしては大きかった。同じ作業を再現したい人向けに、コアな手順をメモ:
- Chrome を
--remote-debugging-port=9223で起動しておく - agent-browser で k-stat にアクセス(ログイン状態を流用するため)
- Chrome DevTools MCP に切り替えて
evaluate_scriptでフォーム操作と DOM 抽出 - ページは
/stat/cstat/peri/item/ItemList.screenを使う(월별 + 同月単発で月次データが取れる) - setSel の順序: 終了月 → 開始月の順で更新。月を逆方向に動かさない
- 年初(1月)は別ルート: s_month を 12→01 に下げてから e_month を 01 にする
- alert は handle_dialog で都度 accept。データは alert 発生前に DOM に乗るので拾える
- 75ヶ月 × 2系列 ≈ 200リクエスト。バッチサイズ12ヶ月で各バッチ約30秒、合計15分
fetchMonth の最終形:
const fetchMonth = async (year, month) => {
if (month === '01') {
setSel('e_year', String(year));
setSel('s_year', String(year));
setSel('s_month', '01');
setSel('e_month', '01');
} else {
setSel('e_year', String(year));
setSel('e_month', month);
setSel('s_year', String(year));
setSel('s_month', month);
}
window.doSearch();
await wait(2200);
// DOMから 8542321010 行を抽出して amt と wgt を取得
};
まとめ
The Economist のチャートを 完全再現はできなかった。でも、HS10桁まで掘ったおかげで「DRAM single(chip)と DRAM modules(HBM)は別物で、AI需要の急騰は modules 側で起きている」という構造は見えた。Economist が "including modules" と書いた一言の重みが、HS code の細分まで掘って初めてわかった。
データは公開チャートで確認できる → /blog/korea-dram-export-prices