はじめに
前回、「メルカリの検索ノイズを非表示にする拡張機能」についての記事を書きました。
前回の記事:メルカリのスパムを非表示に出来るChrome拡張を作った
https://qiita.com/merpro-dev/items/644b1b7bac6e27110461
検索汚染の解決に続き、今回取り組んだのは
「売上データの一括管理」
という課題です。
課題:売上データが取得できない問題
メルカリ(個人アカウント)には、ヤフオクやメルカリShopsにあるような「売上明細のCSVダウンロード機能」がありません。
以前の解決策:GAS × スプレッドシート
これまでは、Gmailに届く通知メールをGAS(Google Apps Script)で解析し、スプレッドシートに転記する仕組みを数年運用してきました。しかし、この方法には以下の課題がありました。
精度の不安定さ: メールの遅延や不具合による転記漏れ、ステータス変更時の重複処理。
汎用性の欠如: 他のユーザーが手軽に利用できる仕組みではない。
解決策としてのブラウザ拡張機能
そこで今回、仕組みを根本から作り直しました。選択したのは「ブラウザ拡張機能(Chrome Extension)」です。
なぜ拡張機能なのか
非スクレイピング: 公式で禁止されている「自動巡回(ボット)」ではなく、ユーザーが閲覧している画面の情報を活用するため、サーバーに過度な負荷をかけません。
公式への配慮: 公式の開発リソースを割くことなく、クライアントサイドの工夫で利便性を補完する「共存型」の解決策になります。
確実なデータ取得: 画面上に表示されている確定情報を直接扱うため、メール経由よりも精度が向上します。
技術スタックと実装
言語: 純粋なJavaScript (Vanilla JS)
ライブラリ: なし
設計思想: 依存関係を最小限にし、軽量動作と保守性を優先。
実装においては、デベロッパーツールでDOM要素を特定し、必要なデータを抽出・整形してCSV化するロジックを構築しました。
1: データの抽出ロジック
/**
* 画面上のリスト要素から商品名と価格を抽出する
*/
const extractSalesData = () => {
// 1. 各取引データが格納されている親要素を特定(環境に合わせて要書き換え)
const itemContainers = document.querySelectorAll('.transaction-item-container');
const results = Array.from(itemContainers).map(container => {
// 2. 子要素から「名称」と「価格」のテキストを取得
const titleElement = container.querySelector('.item-title-label');
const priceElement = container.querySelector('.item-price-value');
// 3. テキストのクリーニングと数値化
const title = titleElement ? titleElement.textContent.trim() : '名称不明';
const priceRaw = priceElement ? priceElement.textContent.trim() : '0';
// 正規表現で数字のみを抽出(「¥1,500」→ 1500)
const price = parseInt(priceRaw.replace(/[^\d]/g, ''), 10) || 0;
return { title, price };
});
return results;
};
const data = extractSalesData();
console.table(data); // 抽出結果の確認
2:CSV出力用の共通関数
/**
* 抽出したオブジェクト配列をCSVとしてダウンロードする
*/
const exportToCSV = (dataList) => {
if (dataList.length === 0) return;
// ヘッダー定義
const headers = ['商品名', '価格'];
const csvRows = [headers.join(',')];
// データのパース
dataList.forEach(item => {
// カンマが含まれる場合の考慮(ダブルクォーテーション囲み)
const escapedTitle = `"${item.title.replace(/"/g, '""')}"`;
csvRows.push(`${escapedTitle},${item.price}`);
});
const csvString = csvRows.join('\n');
// Excelでの文字化け防止(BOM付与)
const bom = new Uint8Array([0xEF, 0xBB, 0xBF]);
const blob = new Blob([bom, csvString], { type: 'text/csv;charset=utf-8;' });
// ダウンロード処理
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = `sales_report_${new Date().toLocaleDateString()}.csv`;
link.click();
};
実際のプラットフォームでは、難読化されたクラス名が使われていたり、定期的にクラス名が変更されたりします。
そのため、本ツールでは document.querySelectorAll('.target-class') のセレクタ部分を、デベロッパーツールで確認した最新の構造に合わせて動的に指定できるように設計しています。
具体的には、**「価格が表示されている要素には必ず共通の親要素がある」**という構造に着目してトラバース(走査)するのがポイントです。
データを可視化してわかったこと
実際に「メルプロ」でデータを抽出し分析したところ、直感と事実のズレが浮き彫りになりました。
直感: 「1万円前後のアイテムが数多く売れており、利益の柱である」
実際: 「より高単価な商品群が、成約数は少なくとも全体の売上高に最も大きく貢献している」
この気づきにより、リサーチの注力先を修正し、目標売上の達成が容易になりました。昨今の物価高において、**「どこに力を入れれば効率的に稼げるか」**をデータで判断できる意義は大きいと感じています。
今後の展望とユーザー募集
現在、この売上分析機能を搭載した「メルプロ」のベータ版ユーザーを募集しています。
Googleフォーム(応募)
https://docs.google.com/forms/d/e/1FAIpQLSdJgPjVqALnbF0-9tLFu_tevYIC6vF6pUNB3Y59SDGVVLebIg/viewform?usp=dialog
また、下記のような追加機能についても検討中です。
特定期間の利益率自動計算
カテゴリー別の売上比率のグラフ化
「こんな機能があれば、物販のDXがさらに進む」といったエンジニア・ユーザー目線のアイデアがあれば、ぜひフィードバックをいただけますと幸いです。
おわりに
プラットフォームの規約を遵守しつつ、ユーザー側の工夫で「不便」を「便利」に変える。ブラウザ拡張機能は、エンジニアにとって最も身近で強力な解決手段の一つだと再認識しました。



