Skip to main content

On This Page

Building a Real-Time TCG Price Tracker: Scraping Virtual DOMs with MutationObserver

2 min read
Share

These articles are AI-generated summaries. Please check the original sources for full details.

🤑 A Price for Everyone 🤑

John A Madrigal developed a custom Chrome Extension to bridge the data gap between Sorcery: Contested Realm’s collection manager and TCGPlayer’s market data. The system utilizes MutationObserver to scrape and inject pricing for cards including high-value Curiosas and Rare Foils exceeding $1,000.

Why This Matters

While platforms like Curiosa.io provide robust deck building tools, they frequently lack integrated financial metrics because scraping dynamic React-based virtual DOMs is technically prohibitive for standard scrapers. This project demonstrates how engineers can leverage MutationObserver and tRPC request interception to synchronize disparate data sources in real-time without official API access, solving the problem of data silos in niche hobbyist communities.

Key Insights

  • MutationObserver API used to detect and scrape dynamic data loading on TCGPlayer, 2026.
  • Intercepting tRPC Batch Requests on Curiosa.io to correlate card metadata with external market prices.
  • Chrome Extension manifest.json architecture used to manage background service workers and content script permissions.
  • Manual scraping triggers implemented to mitigate the risk of rate-limiting or IP banning from TCGPlayer’s servers.

Working Examples

Implementation of MutationObserver to watch the DOM and trigger scraping logic after data loads.

function observeDOM() { const observer = new MutationObserver(() => { clearTimeout(debounceTimer); debounceTimer = setTimeout(tryScrape, DEBOUNCE_MS); }); observer.observe(document.body, { childList: true, subtree: true }); } function tryScrape() { const results = scrapeCurrentPage(); const count = Object.keys(results).length; if (count === 0) return; scrapedOnThisPage = true; const slug = getSetSlugFromUrl(); chrome.runtime.sendMessage({ type: 'SAVE_PRICES', payload: results }, (response) => { if (response?.success) { console.log('Saved entries'); } }); }

Practical Applications

  • Use case: Chrome Extension + MutationObserver to scrape pricing from TCGPlayer for Sorcery: Contested Realm cards.
  • Pitfall: Relying on specific CSS class selectors like ‘.tcg-table-body’; if the host site updates its UI, the injection script will break.
  • Use case: Intercepting tRPC requests on Curiosa.io to identify card versions like Alpha, Beta, or Foil for accurate price matching.
  • Pitfall: Automated high-frequency scraping can lead to server load issues; the developer mitigated this by requiring manual scrape triggers.

References:

Continue reading

Next article

Alibaba Open-Sources CoPaw: A High-Performance Workstation for AI Agent Workflows

Related Content