「メルカリで安い商品を見つけても、ヤフオクで本当に利益が出るか調べている間に売り切れる」
「毎晩リサーチしているが、時給に換算すると割に合わない」
価格差を利用するアービトラージ、つまり市場間の価格差から利益機会を探す手法では、検索回数の多さよりも、同じ条件で継続的に比較できる仕組みが成果を左右します。
そこで役立つのが、商品データの整理、同一商品の照合、手数料計算、候補通知を行うPythonスクリプトです。人間が毎日検索画面を往復する代わりに、プログラムが候補を絞り込み、判断材料をそろえます。
この記事では、メルカリとYahoo!オークション(旧ヤフオク)の価格差を調べるせどり自動化の設計を、初心者向けに順序立てて解説します。
ただし、利益や完全無人運用を保証する内容ではありません。非公式APIへの依存、認証回避、過剰アクセス、自動購入などは、利用規約違反やアカウント制限につながる可能性があります。中古品を仕入れて継続的に販売する場合は古物商許可などの確認も必要です。本記事は一般的な情報提供であり、法律・税務・投資に関する個別助言ではありません。
価格差リサーチを「自動化資産」に変える全体像
アービトラージでは、安く買って高く売れれば必ず利益になるわけではありません。販売手数料、送料、梱包費、不良品、返品、値下がり、売れるまでの期間を差し引く必要があります。
自動化する処理は、次の6段階に分けられます。
許可された方法で商品データを取得
↓
商品名・型番・状態を正規化
↓
同一商品と思われるデータを照合
↓
手数料・送料・リスクを含めて利益計算
↓
基準を満たした候補だけ通知
↓
売買結果を台帳へ戻して判定条件を改善
正規化とは、表記の違いをそろえる処理です。たとえば「Nintendo Switch 有機EL」「Switch OLED」「HEG-S-KAAAA」を、型番を基準に同じ商品候補として扱います。
目標は、検索作業を速くすることではありません。毎日決まった時間に動き、異常がなければ人間の時間を使わず、候補・根拠・期待利益を蓄積する仕組みを作ることです。
一方、個人向けフリマの現物取引には、状態確認、真贋判定、購入、検品、撮影、梱包、発送があります。これらまで無条件に無人化すると、誤購入や規約違反の危険が上がります。
現実的には、まず次の範囲を自動化します。
- データの取得と整形
- 同一商品候補の抽出
- 期待利益と回転速度の計算
- 条件一致時の通知
- 仕入れ・販売・在庫の台帳記録
- 日次レポートと異常検知
購入や出品まで人を介さず運用したい場合は、公式に認められた事業者向け連携、倉庫代行、検品代行、発送代行を組み合わせる必要があります。消費者向け画面をBotで操作する設計とは分けて考えてください。
先に確認したい規約・手数料・法的条件
2026年7月22日の確認時点で、メルカリは販売価格の10%を販売手数料として案内しています。メルカリ公式「メルカリの手数料」
Yahoo!オークションも、個人出品の通常カテゴリについて落札価格の10%を落札システム利用料として案内しています。特定カテゴリやストア契約では条件が異なります。Yahoo!オークション公式「ご利用料金」
また、Yahoo!デベロッパーネットワークの旧オークションWeb APIは、2018年2月22日に提供を終了しています。Yahoo!デベロッパーネットワークの提供終了案内
したがって、過去のブログに掲載されたAPIコードをそのまま利用できるとは限りません。現在使える取得手段と許諾範囲を、実装前に両サービスへ確認してください。
メルカリは、禁止行為が確認された場合に警告や利用制限を行う可能性を案内しています。第三者の画像・文章の無断使用、代理出品、虚偽情報なども禁止対象です。メルカリ公式「禁止されている行為」
中古品を仕入れて営業として販売する場合、古物商許可や本人確認、帳簿管理などが関係します。警視庁は、フリマアプリやインターネットオークションによる仕入れでも、古物商には取引相手の確認義務があると案内しています。警視庁「古物商許可申請をされる方へ」
Pythonによるせどり自動化の作業手順
1. 対象商品を型番で識別できるカテゴリに絞る
最初は、商品名だけで比較しないでください。同じ名称でも、世代、容量、付属品、状態が異なるからです。
初心者には、次のような識別情報がある商品が向いています。
- ゲーム機:型番、容量、限定版
- カメラ:メーカー型番、レンズマウント
- PC周辺機器:型番、接続方式
- 工具:品番、バッテリー規格
- オーディオ機器:モデル番号、発売世代
衣類、宝飾品、トレーディングカード、ブランド品は、状態や真贋による価格差が大きく、写真だけでは機械判定しにくいカテゴリです。自動判定の初期対象から外す方が安全です。
2. データ取得方法を確認する
取得手段は、次の優先順位で検討します。
- 正式に提供されたAPIや事業者向け連携
- 自分の取引履歴や管理画面から出力したデータ
- 利用許諾を得たデータフィード
- 手作業で作成した検証用CSV
- 規約上認められた範囲のページ取得
CAPTCHA回避、ログイン情報の不正利用、アクセス制限の回避、非公開APIの解析は採用しません。
最初の検証では、10〜30商品程度を手作業でCSVへ入力しても構いません。ここで確認するのは大量取得の可否ではなく、「利益計算と商品照合が正しく動くか」です。件数は検証用の前提であり、収益目標ではありません。
3. 比較用CSVの列をそろえる
最低限、次の項目を保存します。
source,item_id,title,model,condition,price,shipping,sold_at,url
mercari,m001,Switch有機EL本体,HEG-S-KAAAA,used_good,12000,750,,https://example.com/1
yahoo,y001,Nintendo Switch OLED,HEG-S-KAAAA,used_good,18000,0,2026-07-20,https://example.com/2
出品中価格と成約価格は分けてください。出品中の3万円は「3万円で売れる」という証拠ではありません。売却価格の推定には、可能な範囲で成約済みデータを利用します。
conditionも共通化します。
CONDITION_MAP = {
"新品、未使用": "new",
"未使用に近い": "like_new",
"目立った傷や汚れなし": "used_good",
"傷や汚れあり": "used_fair",
}
4. 商品名を正規化する
商品名には、空白、全角・半角、装飾記号、不要な宣伝文句が混ざります。
import re
import unicodedata
def normalize_title(value: str) -> str:
text = unicodedata.normalize("NFKC", value).lower()
text = re.sub(r"[【】\[\]★☆!!]", " ", text)
text = re.sub(r"\b(送料無料|即購入可|早い者勝ち)\b", " ", text)
return " ".join(text.split())
ただし、文字列の類似度だけで同一商品と断定してはいけません。型番、容量、色、付属品、状態の一致を確認します。
判定例は次のとおりです。
型番一致 +50点
容量一致 +15点
状態区分一致 +15点
主要付属品一致 +10点
商品名の類似度が一定値以上 +10点
型番不一致 判定対象外
ジャンク・動作未確認 判定対象外
配点は検証用の仮定です。実際の誤一致を記録し、カテゴリごとに調整します。
5. 成約価格の中央値を計算する
平均値は、極端に高い落札や付属品違いの影響を受けます。まずは中央値を採用すると、外れ値の影響を抑えられます。
from statistics import median
sold_prices = [17600, 18000, 18100, 25000, 17900]
estimated_sale_price = median(sold_prices)
print(estimated_sale_price) # 18000
この例の5件は計算方法を示す架空データです。実運用では、型番・状態・付属品が一致した成約データだけを残します。
成約件数が少ない場合は、推定値の信頼度を下げます。
- 成約データ0件:利益判定を停止
- 成約データ1〜2件:参考候補として通知
- 成約データ3件以上:中央値を計算
- 古い成約しかない:更新日を警告表示
件数基準も初期設定例です。商品の回転速度に応じて変更してください。
6. 手数料・送料・リスクを含めて利益を計算する
期待利益は、次の式で計算します。
期待利益
= 予想販売価格
- 販売手数料
- 仕入価格
- 仕入送料
- 販売送料
- 梱包費
- リスク引当額
仮に次の条件を置きます。
- 仕入価格:12,000円
- 予想販売価格:18,000円
- 販売手数料:1,800円
- 仕入送料:0円
- 販売送料:750円
- 梱包費:200円
- 返品・値下がり用の引当額:900円
18,000-1,800-12,000-0-750-200-900
= 2,350円
この条件での仕入額に対する期待利益率は約19.6%です。
2,350 ÷ 12,000 × 100
= 約19.6%
送料と引当額は説明用の仮定です。実際にはサイズ、配送方法、不良率、値下げ履歴から設定します。
Pythonでは次のように計算できます。
def calculate_profit(
sale_price,
purchase_price,
fee_rate,
inbound_shipping,
outbound_shipping,
packing_cost,
risk_reserve,
):
fee = sale_price * fee_rate
profit = (
sale_price
- fee
- purchase_price
- inbound_shipping
- outbound_shipping
- packing_cost
- risk_reserve
)
roi = profit / purchase_price if purchase_price else 0
return round(profit), round(roi * 100, 1)
7. 通知条件を設定する
利益が1円でも出る候補を通知すると、確認作業が増えます。通知条件は、利益額、利益率、成約件数、データ更新時刻を組み合わせます。
def should_alert(item):
return (
item["expected_profit"] >= 2000
and item["roi"] >= 15
and item["sold_count"] >= 3
and item["match_score"] >= 80
)
2,000円、15%、3件、80点は初期検証用の仮定です。カテゴリー別の返品率や作業時間を計測してから変更します。
通知には商品URLだけでなく、根拠を添えます。
型番:HEG-S-KAAAA
仕入候補:12,000円
成約中央値:18,000円
期待利益:2,350円
期待利益率:19.6%
比較成約数:5件
一致スコア:90点
注意:付属品と動作状態は未確認
8. 売買結果を台帳へ戻す
通知して終わると、Pythonスクリプトは改善されません。候補ごとに結果を残します。
- 通知日時
- 購入したか
- 見送った理由
- 実際の仕入額
- 実際の販売額
- 売れるまでの日数
- 値下げ額
- 返品・キャンセル
- 実利益
- 人間の作業時間
この台帳が蓄積すると、「利益率は高いが売れない商品」「計算上は薄利でも回転が速い商品」が見えるようになります。
9. 定期実行と障害通知を追加する
Windowsならタスクスケジューラ、Linuxならcron、クラウドなら定期実行サービスを利用できます。
毎回、次の情報をログへ残してください。
run_id
開始・終了時刻
取得件数
正規化件数
照合成功件数
通知件数
エラー件数
データの最終更新時刻
処理が動かなかった日は「候補0件」と区別します。取得0件、認証エラー、処理成功だが候補0件は、それぞれ意味が異なります。
Hiroの自動ブログ運用ログから分かった監視の必要性
このサイトの auto-ai-blog リポジトリを2026年7月22日に再計測したところ、3サイトの投稿Markdownは次の件数でした。
| サイト | 記事数 |
|---|---|
| AI・テック | 343件 |
| ビジネス | 398件 |
| 不動産 | 130件 |
| 合計 | 871件 |
品質検査、記事取り込み、サイト振り分け、商品ページ構造に関する8テストも実行し、すべて終了コード0で通過しました。
........ [100%]
一方、同日の生成ログには、AIレビュー処理が240秒でタイムアウトし、下書きや改善済み記事へ切り替えた記録が残っています。
review: codex CLI failed: CLI timeout after 240s
Review stage failed; using draft
final_check: codex CLI failed: CLI timeout after 240s
Final check failed; using improved article
871記事や8テストは、このサイトのコンテンツ運用実績です。メルカリ・Yahoo!オークションでの利益や、価格照合精度を示す数字ではありません。
ここから得られる教訓は、完全自動化には成功ルートだけでなく、停止を検知し、安全な状態へ戻すルートが要るという点です。価格取得が壊れた日に古いデータで購入判定を続ければ、止まるより大きな損失が出る可能性があります。
専門家目線のチェックポイント
出品価格ではなく成約価格を使っているか
高額な売れ残り商品を比較対象にすると、期待利益が過大になります。成約日、状態、付属品まで確認します。
型番の一致を最優先しているか
「PS5本体」という商品名だけでは、通常版、デジタル・エディション、旧型、新型を区別できません。型番が取れない商品は、自動購入候補から外します。
送料を固定値にしていないか
同じ商品でも、箱の有無や梱包後のサイズで送料が変わります。実際の配送実績からカテゴリ別の送料中央値を作ります。
売れるまでの期間を見ているか
期待利益3,000円でも販売まで90日かかる商品は、資金と保管場所を拘束します。利益率と同時に在庫回転日数を評価します。
自動購入を急いでいないか
状態説明の不足、偽物、欠品、アカウント乗っ取り、相場急落は、価格だけでは判定できません。研究段階では通知までを自動化し、購入前に写真・説明・出品者情報を確認します。
画像で説明すべき箇所と視覚的証拠
記事へ追加すると理解が深まる画像は、次の3種類です。
データフロー図
取得、正規化、照合、利益計算、通知、台帳更新の流れを矢印で示す。候補通知のスクリーンショット
型番、仕入価格、成約中央値、期待利益、成約件数、警告を一画面に表示する。個人名や取引IDはぼかす。予想利益と実利益の比較グラフ
横軸を商品、縦軸を金額にして、送料超過、値下げ、返品による差を可視化する。
収益画面だけを掲載するより、取得日時、計算式、失敗ログを一緒に提示した方が検証可能な証拠になります。
よくある失敗と対策
似た商品を同一商品として扱う
対策:型番不一致を除外し、容量・色・付属品を別項目にする。販売手数料だけ差し引く
対策:往復送料、梱包費、値下げ、返品引当、保守時間まで計上する。取得件数を増やしすぎる
対策:1カテゴリ、10〜30商品程度の検証用データから始める。規約変更を確認しない
対策:規約URL、確認日、取得方法を台帳化し、定期的に見直す。処理成功とデータ正常を混同する
対策:終了コードだけでなく、取得件数、更新時刻、欠損率を検査する。通知が多すぎて見なくなる
対策:期待利益、利益率、成約数、一致スコアの複数条件で絞る。完全無人化を先に目指す
対策:リサーチ、計算、通知、記録から自動化し、誤判定率が把握できてから対象範囲を広げる。
成果を測るKPI
| KPI | 計算方法 | 改善に使う判断 |
|---|---|---|
| 商品一致精度 | 正しく一致した件数 ÷ 確認件数 | 正規化・型番抽出を改善 |
| 候補採用率 | 購入候補になった件数 ÷ 通知件数 | 通知条件を調整 |
| 予想利益誤差 | 実利益-予想利益 | 送料・引当額を修正 |
| 在庫回転日数 | 仕入日から販売日までの日数 | 対象カテゴリを見直す |
| 返品・キャンセル率 | 問題取引件数 ÷ 成約件数 | 状態判定を厳格化 |
| 自動実行成功率 | 正常終了回数 ÷ 予定実行回数 | 監視と再実行を改善 |
| 人間作業時間 | 調査・確認・梱包・対応の合計 | 外注や追加自動化を判断 |
| 時間当たり実利益 | 実利益 ÷ 人間作業時間 | 自動化資産として評価 |
売上だけでは、人間の時間を消耗しているか判定できません。人間作業時間と実利益を同じ台帳で測ると、不労所得に近づいているのか、忙しい小売業を作っているのかを区別できます。
次に取るべき行動
今日できる最初の作業は、対象商品を10件選び、次の列を持つCSVを作ることです。
型番/状態/仕入価格/成約価格/販売手数料/送料/梱包費/期待利益
そのCSVに対して利益計算用のPythonスクリプトを動かし、手計算と一致するか確認してください。取得処理を作るのは、その後です。
この順番なら、取得方法が変わっても利益計算と台帳を再利用できます。毎日の検索結果を消費するのではなく、判定ルール、失敗履歴、成約データが積み上がる自動化資産へ変えられます。
本気で自動化・不労所得を構築したい方へ
「Pythonコードは動いた。でも、監視・再実行・収益計測までつながらない」
その状態から抜け出すには、単発のサンプルコードではなく、止まっても復旧し、利益と作業時間を記録しながら育つ運用設計が必要です。
本気で人間の作業を減らし、寝ている間も情報収集・判定・通知・記録が進む仕組みを作りたい方へ、実装手順、チェックリスト、収益導線をまとめた実践マニュアルを用意しています。
次の週末も手作業のリサーチで終えるか、繰り返し働く自動化資産を作り始めるか。