การพลิกแผ่น Pokémon Slab นั้นง่ายมาก ปัญหาคือข้อเสนอดีๆ บน Mercari, eBay และ Vinted อาจถูกหยิบไปภายในไม่กี่นาที หรือหาได้ยากมาก และไม่มีมนุษย์คนไหนจะคอยตรวจสอบทุกประกาศขายบนตลาดทั้งสามแห่งได้ตลอด 24 ชั่วโมง
ผมเลยให้ Claude Code สร้างตัวเฝ้าดูให้ สองวันต่อมา นี่คือสิ่งที่ทำงานตลอด 24 ชั่วโมง 7 วันบน Mac mini ในห้องทำงานของผม:
เครื่องมือ
ทุก 5 นาที มันจะสแกนประกาศขายใหม่บน Mercari, eBay และ Vinted รูปถ่ายของประกาศขายใหม่แต่ละรายการจะถูกส่งผ่าน PokeGrade API ซึ่งระบุการ์ดที่แน่นอนและดึงมูลค่าตลาดสด — ราคาเปรียบเทียบทั้งแบบ Raw และ Graded PokeGrade API คือสิ่งที่ขับเคลื่อนเว็บไซต์ของเราเบื้องหลัง เราให้บริการฟรีสำหรับนักพัฒนา PokeGrade.ai/developers
ถ้า Slab ลงประกาศขายต่ำกว่าราคาตลาด 25% ขึ้นไป ประกาศบน Mercari จะถูกกดหัวใจอัตโนมัติ และที่เหลือทั้งหมดจะส่งการแจ้งเตือนไปยังโทรศัพท์ผม กลยุทธ์สองอย่างทำงานควบคู่กัน: Slab ที่ราคาต่ำกว่าตลาด และแบบที่แปลกกว่า — Slab ที่ราคาต่ำกว่าราคาของการ์ดที่ยังไม่ได้เกรด (การเก็งกำไรแบบ Crack-the-slab; หายาก แต่มีอยู่จริง)

เทอร์มินัล
แดชบอร์ดสด — สไตล์ห้องซื้อขายมืดๆ มีข้อความวิ่ง, ไฟ LED สถานะ — แสดงผลการประเมินทุกครั้ง, ยอดรวมกำไรที่อาจได้พร้อมคำนวณค่าธรรมเนียม, กราฟราคาขายของสินค้าที่ผมกำลังติดตาม (สุ่มตัวอย่างทุก 60 วินาทีจากยอดขายบน eBay), และสมุดบัญชี: วางลิงก์ประกาศขายจากตลาดทั้งห้าแห่ง แล้วสคริปต์ขูดข้อมูลจะบันทึกการซื้อหรือขาย และติดตาม P/L สะสมของผม ในทางทฤษฎี ผมสามารถเชื่อมสคริปต์ของผมกับบัญชีของผมและให้มันขูดข้อมูลทุกชั่วโมง เพียงแค่ยังไม่ได้ทำ เยนและยูโรแปลงเป็นสกุลเงินดอลลาร์อัตโนมัติ ปุ่มเดียวก็ย้ายรายการที่ซุ่มเจอไปยังสมุดบัญชีได้ทันที ใช้งานได้จากโทรศัพท์
ส่วนที่ไม่มีใครบอกคุณ ฟีเจอร์ต่างๆ ใช้เวลาแค่บ่ายเดียว ส่วนอีกวันครึ่งคือการต่อสู้กับความเป็นจริง: ระบบตรวจจับบอทของตลาดที่ปฏิเสธเบราว์เซอร์อัตโนมัติ, หน้าที่แสดงโค้ดแตกต่างกันไปตามว่าคุณล็อกอินหรือไม่, การ์ดญี่ปุ่นที่ซ่อนอยู่หลังชื่อภาษาอังกฤษ, macOS ที่ฆ่างานพื้นหลังที่อยู่ในโฟลเดอร์ผิดอย่างเงียบๆ แต่ละอย่างใช้เวลาหลายชั่วโมงในการวินิจฉัยและแก้ไขเพียงบรรทัดเดียว
นั่นคือเหตุผลที่ผมแชร์ prompt แทนที่จะเป็นโค้ด prompt นี้มีทุกอย่าง — ตัวเลือกที่ตรวจสอบแล้วทุกตัว, กับดักทุกอัน, การ์ดทุกใบ — เพื่อให้การสร้างของคุณข้ามการต่อสู้กับความเป็นจริงไปได้
กฎที่ทำให้ปลอดภัย prompt นี้ ไม่เคย ซื้ออะไร ไม่เคย ส่งข้อเสนอ ข้อเสนอที่ "ดีเกินจริง" (อัตราส่วน 5x+) จะถูกทำเครื่องหมายว่าน่าสงสัยแทนที่จะฉลอง เพราะมันมักจะเป็นประกาศขายที่ไม่น่าเชื่อถือหรือ AI เปรียบเทียบการ์ดผิด มนุษย์จะตรวจสอบข้อเสนอทุกรายการก่อนที่จะมีการโอนเงิน สร้างในแบบเดียวกัน — ระบบอัตโนมัติค้นหา คุณตัดสินใจ
ค่าใช้จ่าย: PokeGrade API สำหรับระบุการ์ด (ฟรี 100 ครั้ง/เดือนสำหรับทดลอง; เสียเงินถ้าสแกนจริงจัง), บัญชีนักพัฒนา eBay ฟรี, และคอมพิวเตอร์ที่เปิดทิ้งไว้ เท่านั้น
Prompt
คัดลอกทุกอย่างด้านล่างนี้ไปยัง Claude Code กรอกข้อมูลสามจุด และสร้างทีละเฟส (แต่ละเฟสมีประโยชน์ในตัวเอง)
ฉันต้องการชุดเครื่องมือพลิกการ์ดส่วนตัวบนคอมพิวเตอร์ สร้างเป็นชุดบริการพื้นหลังที่จัดการโดย launchd (หรือเทียบเท่าบน Windows) บวกกับแดชบอร์ดเว็บในเครื่อง สแต็ค: Node.js + Playwright, ไม่มีเฟรมเวิร์ก, ไม่มีฐานข้อมูล — ไฟล์ CSV/JSON ในโฟลเดอร์โปรเจกต์เดียว ทุกอย่างต้องอยู่รอดหลังการรีบูต ฉันจะส่ง 5 เฟสให้คุณ หลังจากแต่ละเฟสเสร็จสมบูรณ์ โปรดแจ้งให้ฉันทราบว่าคุณพร้อมสำหรับเฟสถัดไป มีคีย์ API บางส่วน และเฟส 1 เป็นอันดับแรก
อินพุตของฉัน (กรอก):
PokeGrade API key: PGAI_KEY_HERE (จาก
pokegrade.ai/developers — เอ็นด์พอยต์ /value ระบุการ์ดจากรูปถ่ายหนึ่งรูปและส่งคืนราคาตลาดแบบ raw + graded; เอกสารที่
eBay production keyset: EBAY_CLIENT_ID / EBAY_CLIENT_SECRET (ฟรีที่
developer.ebay.com ; สมัครขอยกเว้นการลบบัญชีเพื่อเปิดใช้งาน)
เกณฑ์ข้อเสนอของฉัน: กดหัวใจ/แจ้งเตือนที่มูลค่าตลาดอย่างน้อย 1.25 เท่าของราคาที่ขอ; แถบรายการเสนอซื้อที่ 1.15-1.25 เท่า (กำไรสุทธิประมาณ 26% หลังจากยอมรับข้อเสนอ 80% และค่าธรรมเนียมการขายประมาณ 12%)
เฟส 1 — Mercari sniper (กดหัวใจอัตโนมัติ)
บริการที่สแกนการค้นหา Mercari ทุก ~10 นาที, กำหนดราคา รูปถ่ายแรก ของประกาศขายใหม่แต่ละรายการผ่าน PokeGrade /value, และกดหัวใจประกาศที่ผ่านเกณฑ์ข้อเสนอ สองกลยุทธ์จากอาร์เรย์การตั้งค่า, หนึ่งกระบวนการเบราว์เซอร์:
raw-crack: ค้นหา "pokemon psa 8", เปรียบเทียบมูลค่า RAW (ยังไม่เกรด) — พบ Slab ที่คุ้มค่าที่จะแตก (raw > ราคา Slab; หายากแต่มีจริง) graded-under: ค้นหา psa 8/9/10, เปรียบเทียบราคาเปรียบเทียบของ Slab เกรดนั้นเอง
ข้อเท็จจริงการนำไปใช้ที่สำคัญ (ตรวจสอบแล้ว จะช่วยคุณประหยัดเวลาได้หลายชั่วโมง):
การตรวจสอบบอทของ Mercari (PerimeterX) ปฏิเสธ Chromium ในตัวของ Playwright อย่างหนัก — ความท้าทายกดค้างจะวนซ้ำไม่รู้จบ เปิด Chrome ที่ติดตั้งจริง: channel:'chrome', headful, persistent profile dir, --disable-blink-features=AutomationControlled, ignoreDefaultArgs:['--enable-automation'] ห้ามทำให้การล็อกอินเป็นอัตโนมัติ: ตรวจจับเมื่อไม่ได้ล็อกอิน (การเยี่ยมชม /mypage/ จะเปลี่ยนเส้นทาง CLIENT-SIDE หลังจาก ~15 วินาทีไปยัง /login/?login_callback=... — ตรวจสอบ URL, ไม่ใช่ DOM) และรอสูงสุด 30 นาทีให้มนุษย์ล็อกอินครั้งเดียว; เซสชันจะคงอยู่ในโปรไฟล์
หน้าที่ล็อกอินแล้วกับไม่ได้ล็อกอินใช้ test id ที่แตกต่างกัน การค้นหาที่ล็อกอินแล้ว: ไทล์ a[data-testid="ProductThumbWrapper"], ราคา ProductThumbItemPrice (ไม่ได้ล็อกอิน: ItemPrice — ยอมรับทั้งสอง), หัวใจไทล์ ItemLike (ภายใน anchor ของไทล์ — กดหัวใจจากหน้าค้นหา, ไม่ต้องเปิดประกาศ), หัวใจหน้ารายการสินค้า LikeComp ProductThumbItemDiscountedPrice คือราคาเดิมที่ขีดฆ่า — ห้ามใช้เด็ดขาด; ไทล์ที่มีส่วนลดจะรวมราคาทั้งสองในโหนดข้อความเดียว ("$99.75$105") ดังนั้นให้แยกเฉพาะโทเค็นเงินแรกเท่านั้น
รูปถ่ายแรกของประกาศไม่ต้องเข้าหน้า:
https://u-mercari-images.mercdn.net/photos/ITEMID_1.jpg (fetch ธรรมดา)
"ใหม่" = item id ที่ยังไม่เคยประเมิน (ไฟล์สถานะ), เรียงใหม่ที่สุดก่อน, ข้ามไทล์ที่ขายแล้ว การเรียก PokeGrade แต่ละครั้ง = 1 เครดิต — แคชผลลัพธ์ต่อ item id ตลอดไปและแชร์แคชระหว่างกลยุทธ์ ติดตาม id ที่กดหัวใจแยกจาก id ที่เห็น (การขัดข้องระหว่างการเกรดและการกดหัวใจต้องไม่ทำให้เกิดการคลิกสองครั้ง ซึ่งจะยกเลิกหัวใจ) ความล้มเหลวชั่วคราว (API 5xx, ไม่มีราคา) จะไม่ถูกนับว่าเห็นและลองใหม่ในรอบถัดไป
ข้อควรระวัง launchd: agent ไม่สามารถอ่าน ~/Desktop (TCC) — งานจะตายอย่างเงียบๆ ด้วย exit 78 เก็บโปรเจกต์ไว้ในโฟลเดอร์ home, ไม่ใช่ Desktop ใช้ RunAtLoad + KeepAlive; ใช้เส้นทาง node แบบสัมบูรณ์ใน plist
เฟส 2 — ฟีด eBay + Vinted (แจ้งเตือนเท่านั้น)
กลยุทธ์/เกณฑ์เดียวกัน แต่ไม่มี API รายการเฝ้าดู ดังนั้นข้อเสนอจะส่งการแจ้งเตือน macOS (osascript display notification) + แถว CSV แทนการกดหัวใจ/รายการโปรด
eBay: ใช้ Browse API อย่างเป็นทางการ (OAuth ข้อมูลประจำตัวไคลเอ็นต์, item_summary/search, sort=newlyListed, filter buyingOptions FIXED_PRICE + itemLocationCountry US — หมายเหตุ priceCurrency จะใช้ได้ก็ต่อเมื่อมีช่วงราคา) อัปเกรด URL รูปภาพ s-l225 เป็น s-l1600 สำหรับ OCR ประมาณ 5,000 การเรียก API/วันที่ 3 การค้นหาต่อ 10 นาทีก็ใช้ได้; PokeGrade burn คืองบประมาณจริง (ประมาณ 5,000 เครดิต/วันที่ปริมาณ eBay — จำกัดการประเมินต่อการค้นหา เช่น 15)
Vinted: ขูดข้อมูลแคตตาล็อก (ไม่มี API แต่ไม่มีกำแพงบอทเช่นกัน) ไทล์: a[data-testid="product-item-id-ID--overlay-link"] ที่แอตทริบิวต์ title มี "name, brand: X, condition: Y,
$price "; รูปภาพที่ [data-testid="...--image"] img (เพิ่มส่วน URL /f###/ เป็น /f800/) หน้า Vinted จะทำให้ headless Chromium ขัดข้องประมาณ 1 ใน 3 ครั้งที่โหลด และอาจค้างโดยไม่โยนข้อผิดพลาด — ห่อการขูดทุกครั้งด้วย Promise.race ตัวจับเวลา 90 วินาที และเปิดเบราว์เซอร์ใหม่เมื่อเกิดความล้มเหลว บันทึกบรรทัด heartbeat ทุกรอบเพื่อให้บันทึกที่เงียบหมายถึง "ติดขัด" ไม่ใช่ "เงียบ"
การป้องกันคุณภาพ (ทั้งหมดเรียนรู้จาก false positive จริง):
ก่อนใช้เครดิต: ข้ามชื่อที่ระบุว่าเป็นล็อต/ชุด หรือกล่าวถึง japanese/chinese/korean/german/french/etc.
หลังการระบุ: ปฏิเสธถ้าชุดที่ระบุโดย PokeGrade เป็นตลาดต่างประเทศ (โทเค็น JP/CS/CN/KR) — ผู้ขายซ่อนภาษาจากชื่อ
กับดัก Celebrations: PokeGrade อาจระบุฉบับพิมพ์ซ้ำ "Classic Collection" ของ Celebrations ผิดเป็นต้นฉบับวินเทจ (ฉบับพิมพ์ซ้ำ $30 เปรียบเทียบเป็น $30,000) ถ้าชื่อระบุ celebrations/classic collection แต่ชุดที่ระบุไม่ใช่ ให้ทิ้งราคาเปรียบเทียบ ความเสี่ยงฉบับพิมพ์ซ้ำเดียวกัน: Base Set 2, XY Evolutions
สิ่งใดก็ตามที่มีอัตราส่วน 5 เท่าหรือมากกว่าจะถูกทำเครื่องหมาย "น่าสงสัย — ต้องตรวจสอบ" และไม่รวมจากรายได้หลัก (อัตราส่วนที่สูงมากมักจะเป็นการเปรียบเทียบที่ไม่ตรงกัน ไม่ใช่รางวัลใหญ่)
เฟส 3 — แดชบอร์ด (เว็บแอป localhost)
เซิร์ฟเวอร์ HTTP Node ไร้การพึ่งพาเดียว (ผูก 0.0.0.0 เพื่อให้โทรศัพท์ใน LAN เปิดได้) ที่ให้บริการไฟล์ HTML หนึ่งไฟล์ซึ่งสอบถามเอ็นด์พอยต์ /data ทุก 30 วินาที สไตล์ "trading terminal" มืดเป็นหลัก: ตัวเลข monospace, ไฟ LED สถานะต่อบริการ (mtime ของไฟล์บันทึก = สุขภาพ), ข้อความวิ่งของการประเมินล่าสุด, แอนิเมชันนับเลข สามแท็บ:
1. Sniper — แถบสถิติ (กำไรที่อาจได้หลังหักค่าธรรมเนียม ไม่รวมรายการต้องสงสัย, ข้อเสนอ, ข้อเสนอซื้อ, ต้องตรวจสอบ, ประเมินแล้ว), แผนภูมิกิจกรรมการสแกนต่อชั่วโมง, แผนภูมิรายได้สะสม, การแจกแจงคำตัดสิน, กระดานคะแนนกลยุทธ์, และตารางรายการที่พบที่เรียงลำดับได้พร้อมรูปย่อประกาศ, สลับดาว/รายการโปรด (กรองได้), และปุ่ม "ซื้อแล้ว" ที่คัดลอกรายการที่พบไปยังสมุดบัญชีทันที
2. Market watch — ตัวติดตามราคาขาย (เฟส 4)
3. สมุดบัญชี — เฟส 5
ให้บริการรูปภาพภายนอกผ่านพร็อกซี /thumb ที่เป็น same-origin (ไวท์ลิสต์ CDN ของตลาด) — รูปภาพ cross-origin/hotlinked จะถูกบล็อกในบางไคลเอ็นต์ รายการที่พบที่น่าสงสัย: ป้ายคำเตือน + ไม่รวมจากยอดรวม
เฟส 4 — ตัวติดตามราคาขายในตลาด
ข้อมูลการขายบน eBay ไม่อยู่ใน API สาธารณะ ขูดข้อมูลการค้นหาขายแล้ว (LH_Sold=1, LH_Complete=1, sort ใหม่ที่สุด) ด้วย headless Chromium (channel:'chromium'), ปลอม browser-UA, และเยี่ยมชมหน้าแรกเพื่ออุ่นเครื่องก่อน (การเข้าลึกโดยตรงโดยไม่อุ่นเครื่องจะถูกบล็อกบอท) การ์ด: องค์ประกอบ [data-listingid]; รายการที่ขายจริงจะมีบรรทัด "วันที่ขาย" (โฆษณาสปอนเซอร์ไม่มี) ทุกนาที สำหรับแต่ละคำค้นหาที่กำหนดค่าไว้: รับราคาขายล่าสุด 10 รายการ, ต่อท้าย avg/median/min/max ลงใน CSV แดชบอร์ดสร้างกราฟเส้นเฉลี่ย + แถบ min-max ต่อตัวติดตามพร้อมปุ่มซูมช่วงเวลา +/- สคริปต์ backfill แบบครั้งเดียวจะเดินหน้าผลลัพธ์สูงสุด 10 หน้า โดยจัดกลุ่มตามวันที่ขายที่พิมพ์เพื่อสร้างประวัติรายวันประมาณหนึ่งสัปดาห์ (idempotent) พัก 10 นาทีหลังจาก 3 การสกัดที่ว่างเปล่าติดต่อกัน
เฟส 5 — สมุดบัญชี (ซื้อ/ขาย P/L)
แท็บสมุดบัญชีพร้อมอินพุต BUY และอินพุต SELL: วาง URL ประกาศขายใดก็ได้จาก
japan.us.mercari.com (หน้าร้านค้าข้ามพรมแดน),
ebay.com (รวมถึง
ebay.io ลิงก์สั้นแชร์แอป), หรือ
vinted.com สคริปต์ดึงข้อมูลแบบกำหนด (ไม่มี AI) จะแยกชื่อ/ราคา/สกุลเงิน/รูปภาพ:
หลัก:
schema.org JSON-LD สินค้า (ตรงกับ jp.mercari, ebay, vinted)
japan.us .mercari ไม่มี JSON-LD — ราคาอยู่ที่ [data-testid="main-price"] (สัญลักษณ์และตัวเลขในบรรทัดแยกกัน), เป็น USD อยู่แล้ว
ebay.io ลิงก์สั้นจะแก้ไขได้ในเบราว์เซอร์จริงเท่านั้น และมักจะไปที่หน้า error — ดึง item id จาก URL ที่แก้ไขแล้วเรียก Browse API get_item_by_legacy_id แทน
ปฏิเสธหน้าท้าทายบอท ("Just a moment...", "Error Page") เป็นข้อผิดพลาด — ห้ามเก็บเป็นรายการเด็ดขาด
แปลงสกุลเงินที่ไม่ใช่ USD ผ่าน
frankfurter.app (ECB, ฟรี, แคช 12 ชม.) เก็บรายการใน ledger.json; ยอดรวมสะสม = ขายลบซื้อ, บวกตัวเลขหลังหักค่าธรรมเนียม 12%; แถวแสดงรูปย่อ, ป้ายตลาด, ราคาสกุลเงินท้องถิ่น + USD, และปุ่มลบที่ต้องยืนยัน ราคาที่บันทึก = ราคาที่ประกาศ (ไม่สนใจข้อเสนอ) — นั่นคือการทำให้ง่ายขึ้นโดยเจตนา
การตรวจสอบการยอมรับต่อเฟส
รันหนึ่งรอบจริงและแสดงบันทึกให้ฉันดู; ตรวจสอบประกาศจริงแบบ end-to-end ผ่าน PokeGrade ก่อนต่อลูป; หลังจากเปลี่ยน UI ใดๆ ให้ถ่ายภาพหน้าจอแดชบอร์ดทั้งในโหมดสว่างและมืด; ห้ามทิ้งรายการทดสอบในสมุดบัญชีของฉันหรือหัวใจทดสอบในบัญชีของฉัน
คำเตือนที่ยุติธรรมก่อนที่คุณจะรัน: สคริปต์ขูดข้อมูลอยู่ในโซนสีเทากับ ToS ของตลาด — ให้ความถี่อ่อนโยนและคาดหวัง captcha เป็นครั้งคราว การระบุการ์ดด้วย AI ผิดบ่อยพอที่จะทำให้การซื้ออัตโนมัติเป็นการเผาเงิน และค่าธรรมเนียมที่คุณเจออาจแตกต่างจาก 12% ของผม — ปรับเกณฑ์ใหม่
ถ้าคุณสร้างขึ้นมา ให้แสดงให้ผมเห็นว่ามันเจออะไร





