cd ../projects

TCG Data Platform

"Real-time market price tracking, then population report aggregation — a two-phase data platform for the TCG collecting community."

Legend of blue eyes box

Two-phase data platform built for TCG influencer Strictly Sealed: real-time market price tracking across six marketplaces, then multi-source population and rarity aggregation from every major grading house.

1. The Genesis

It's no secret that I've been into trading cards for a while. Perhaps it's just a heavy dose of nostalgia for my youth? Either way, it eventually led me to collecting the items I could only dream about as a kid. That hobby eventually brought me to a YouTube video by the influencer Strictly Sealed.

I joined his Discord and we chatted casually. Eventually, the conversation turned to tech, and I mentioned that automating his market data collection would be a game-changer. It was a perk he offered through his Patreon, but at the time, the process was entirely manual. It was tedious and, to say the least, a massive pain. That's when I took my first dive into the world of web scraping, moving beyond my background in raw Python.

The task was clear: for each major selling platform, we needed a script capable of pulling screenshots of sales to be posted directly to Discord.

2. Phase 1 — Market Data

The Biggest of Them All: eBay

Who hasn't used eBay? It's a great platform (if you can ignore the seller fees). You can run auctions, buy at a fixed price, or even send offers. The biggest advantage of eBay is that it allows you to query through sold items and sort by sale date—though the downside is it doesn't always confirm if an item was actually paid for. The platform also lacks heavy anti-bot restrictions; using undetected-chromedriver is usually more than enough.

Last ebay sold site
The output of a search through "completed sales" on eBay.

From there, the job is straightforward. Automating the decision of "which sale is relevant" is still a project for the future. For now, the user browses the results, picks the relevant sales, and pastes the URLs into a text file. The bot then verifies the date is current—funnily enough, eBay occasionally pushes year-old sales to the top of the "most recent" list.

Then comes another quirk: clicking a sale should land you on the item page to be screenshotted. However, sometimes—and I suspect this is linked to payment status—you land on a completely irrelevant page. The bot has to cross-reference the URL and item title to ensure it's on the right page before taking the shot. But what happens if an item sold for a "Best Offer" or the page simply isn't accessible?

Ebay sold item picture
The output the bot produces in a "good scenario."

Enter our best friend: 130points. This site is eBay search on steroids. It reveals the actual "Best Offer" price and provides clean screenshots even when the original eBay page is dead. For every eBay item parsed, we double-check it on 130points if:

  • The eBay item page wasn't reachable.
  • The item sold for a Best Offer, and the final price differs from the listed one.
Ebay sold item picture
The screenshot produced if the eBay picture couldn't be captured.

Finally, we crop the images. If the eBay item was accessible but an offer was accepted, we send the eBay photo along with a tight crop of the 130points price data for clarity.

Other Platforms

eBay was the hardest part due to that required double-verification. Other platforms we scraped included Fanatics Collect, alt.xyz, Mercari, Yahoo Japan Auctions (to track Japanese data), and Heritage Auctions (for high-end items). While the process was similar, one detail was crucial: file naming. We wanted every file named exactly after the item being viewed.

This was easy for eBay and Heritage, but for Mercari and Yahoo Japan, I had to handle Japanese text. I built a self-populating translation database with a helper script. For each Japanese listing, it parses the name character-by-character against a Yu-Gi-Oh database to find a mapping, then uses Google Translate for any remaining parts.

3. Phase 2 — Population Reports

If you've spent any time in the TCG world lately, you've seen graded cards: encased in thick, sonically-welded plastic slabs with a numeric grade at the top. To the uninitiated, it looks like someone took a perfectly good game piece and turned it into a museum artifact. But in this market, that plastic "slab" is everything.

Grading is the process of sending a card to a third-party company—like PSA, BGS, or CGC—where an expert examines it under a microscope to judge its condition on a scale from 1 to 10. A "Gem Mint 10" Charizard can be worth ten times more than a "Near Mint 9," even if the human eye can't tell the difference.

This leads us to the Population Report (or "Pop Report"). This is the official census of how many copies of a specific card exist in each grade. If a card has a "Low Pop," it's scarce, and the price skydives upward. But here's the kicker: these numbers change every single day as more cards get graded. Tracking that evolution across three or four different international grading companies by hand? That's not just tedious—it's impossible. Following the ongoing collaboration on the market-data phase, Strictly Sealed asked if I could generate Excel files containing live population reports for specific cards, initially from PSA and later ARS.

The First Data Source: PSA

PSA is the largest and most well-known grading service. Tracking their trends says a lot about the current market. If the market is growing, we see a global population increase. Knowing the rarity of a card at a glance—and the specific ratio of PSA 9s to 10s—gives you a great idea of how difficult a card is to "Gem" (achieve a 10).

The first step was setting up the Excel sheet with the "interesting" cards. Since I'm lazy, I decided to automate this for the main sets. For early Yu-Gi-Oh!, "interesting" is easy to define: any card rarer than a base rarity (Super, Ultra, Ultimate, or Ghost Rare). I wrote a script to scrape Yugipedia to gather card names and set lists, ordering them all into a master spreadsheet.

The yugipedia card list
The Yugipedia lists scraped for each relevant set.

With the foundation built, I moved on to the PSA website. My strategy was as follows: open the latest report, store all existing card data (names, sets, previous grade counts) in memory, and then crawl the PSA site for current numbers. Finally, the script backs up the previous file and edits the Excel sheet with the new data. If a population count increases, the text turns green, and the previous count is shown in parentheses for context.

PSA's website pop report
PSA's official population report for a specific card set.

The main hurdle was PSA's anti-bot measures. I had to implement some proprietary logic to bypass Cloudflare protections. Additionally, mapping the scraped names to the Excel list was painful; PSA's wording is inconsistent, often shifting between different labels for rarities or 1st Edition specs. Refining this took time to ensure the process was robust enough to handle these naming quirks.

Final Excel Report

ARS Grading — and a Self-Expanding Pool

While BGS or CGC are popular, ARS Grading is highly regarded within the Yu-Gi-Oh! community for its reliability and premium aesthetic. However, ARS is based in Japan, and their reports are entirely untranslated. Searching for specific cards requires digging through Japanese names, which is a significant barrier for Western collectors.

Unlike PSA, ARS doesn't store entire sets on one page; they use "single card" pages. To solve this, I returned to Yugipedia to collect the Japanese names for our target sets. I then built a utility script to navigate the ARS search feature, identify the correct card pages, and map the URLs to our database.

ARS Search page
Navigating the Japanese-only ARS Grading search interface.
ARS Card page

Once the URLs were harvested, I reused my core parsing functions to open, scrape, and update the master Excel. The result was a game-changer: English-speaking collectors could finally track the rarity of ARS-graded cards with a single click, providing a much clearer picture of the global supply for high-end TCG items.

But manually maintaining the URL pool as new sets released was its own problem. The solution: a self-expanding discovery script. When a new set drops, the script hits Yugipedia to identify newly relevant cards (rarity threshold: Super Rare and above), retrieves their Japanese names, searches ARS's interface for each one, and — if a matching card page exists — automatically adds the URL to the scraping pool. No human intervention needed. New cards get picked up on the next run, translated names are resolved via the same Yu-Gi-Oh database used in Phase 1, and the Excel report grows itself.

4. Closing the Loop — Discord Integration

The final piece was delivery. Running scripts locally and manually uploading Excel files to Discord channels isn't a pipeline — it's just automation with extra steps. The natural endpoint was the Strictly Sealed Discord bot.

The bot now handles report delivery end-to-end: when a new population report is generated, the bot posts it directly to the relevant Discord channel — formatted, timestamped, and ready for the community. What used to be a manual copy-paste step is now fully hands-off. The scraper runs, the Excel updates, the bot posts. Done.

Taken together, the two projects form a closed loop: Phase 1 and Phase 2 feed live data into the community, and the bot handles both the contest engine and the data delivery — all running on the same €4.51/month VPS.

5. Result

What started as a casual conversation in a Discord server turned into a two-phase data platform: real-time market price automation, followed by cross-grading-house population tracking — with a self-expanding card pool and automated Discord delivery. Both phases replaced hours of tedious, decentralized work with automated pipelines — bridging raw Python scripts with specialized platforms like eBay, 130points, PSA, and ARS Grading, and handling multi-language data (Japanese auctions, Japanese-only grading reports) along the way.

Building this wasn't just about the code — it was about understanding the specific friction points of the TCG market and solving them. Every challenge, from bypassing anti-bot measures to cleaning up inconsistent naming conventions, was a step toward a more transparent market for the community.

6. A Word from Strictly Sealed

"Exqd1a did an unbelievable job optimizing the scraping/integration of the pop report data. But the more impressive work was the accuracy and potency of the sales data accumulation. He was not only able to create a protocol that rips sales data that is accurate and timely, he was able to transcend that by including item categories and products that I personally had never thought to include in the sales data accumulation in the first place. Amazing work."
Yu-Gi-Oh trading card grid layout with an embedded community chat screenshot

Interested in my work?

Let's Talk