Introduction
In this tutorial, we'll explore how to build a Pokémon card collection tracking system using Python and web scraping techniques. This project will help you monitor Pokémon card prices, track your collection, and identify which cards are trending in the market. We'll use APIs and web scraping to gather data, then create a simple dashboard to visualize your collection.
Prerequisites
Before starting this tutorial, you should have:
- Basic Python programming knowledge
- Python 3.7 or higher installed
- Intermediate understanding of APIs and web scraping concepts
- Experience with JSON data manipulation
- Basic knowledge of data visualization libraries
Step-by-step instructions
1. Setting up the Project Structure
1.1 Create Project Directory
First, create a new directory for our Pokémon collection tracker:
mkdir pokemon_tracker
cd pokemon_tracker
1.2 Install Required Libraries
Install the necessary Python libraries for our project:
pip install requests beautifulsoup4 pandas matplotlib seaborn
2. Creating the Data Collection Module
2.1 Setting up the Pokémon API Client
We'll use the Pokémon TCG API to fetch card data. Create a file called pokemon_api.py:
import requests
import json
API_BASE_URL = "https://api.pokemontcg.io/v2"
API_KEY = "your_api_key_here" # Get from https://pokemontcg.io/
def get_pokemon_cards(set_name=None, page=1, page_size=100):
"""
Fetch Pokémon cards from the API
"""
headers = {
"X-API-Key": API_KEY
}
params = {
"pageSize": page_size,
"page": page
}
if set_name:
params["q"] = f"set.name:{set_name}"
try:
response = requests.get(f"{API_BASE_URL}/cards", headers=headers, params=params)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f"Error fetching data: {e}")
return None
def get_card_details(card_id):
"""
Get detailed information about a specific card
"""
headers = {
"X-API-Key": API_KEY
}
try:
response = requests.get(f"{API_BASE_URL}/cards/{card_id}", headers=headers)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f"Error fetching card details: {e}")
return None
2.2 Web Scraping for Price Tracking
Create a price_scraper.py file to scrape price information:
import requests
from bs4 import BeautifulSoup
import time
HEADERS = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}
def scrape_card_price(card_name, site="tcgplayer"):
"""
Scrape price information for a Pokémon card
"""
if site == "tcgplayer":
search_url = f"https://www.tcgplayer.com/search/pokemon?productName={card_name.replace(' ', '+')}",
try:
response = requests.get(search_url, headers=HEADERS)
soup = BeautifulSoup(response.content, 'html.parser')
# This is a simplified example - real implementation would need more specific selectors
price_element = soup.find('span', {'class': 'price'})
if price_element:
return float(price_element.text.replace('$', '').replace(',', ''))
except Exception as e:
print(f"Error scraping {card_name}: {e}")
return None
3. Building the Collection Manager
3.1 Creating the Collection Class
Create collection_manager.py to manage your Pokémon card collection:
import json
import pandas as pd
from datetime import datetime
class PokemonCollection:
def __init__(self, filename="collection.json"):
self.filename = filename
self.collection = self.load_collection()
def load_collection(self):
"""
Load collection from JSON file
"""
try:
with open(self.filename, 'r') as f:
return json.load(f)
except FileNotFoundError:
return {}
except json.JSONDecodeError:
return {}
def add_card(self, card_id, card_name, quantity=1, price=None):
"""
Add a card to the collection
"""
if card_id not in self.collection:
self.collection[card_id] = {
"name": card_name,
"quantity": quantity,
"price": price,
"added_date": datetime.now().isoformat()
}
else:
self.collection[card_id]["quantity"] += quantity
self.save_collection()
def remove_card(self, card_id):
"""
Remove a card from the collection
"""
if card_id in self.collection:
del self.collection[card_id]
self.save_collection()
return True
return False
def save_collection(self):
"""
Save collection to JSON file
"""
with open(self.filename, 'w') as f:
json.dump(self.collection, f, indent=2)
def get_collection_summary(self):
"""
Get summary statistics of the collection
"""
total_cards = sum(card["quantity"] for card in self.collection.values())
total_value = sum(
card["quantity"] * card.get("price", 0)
for card in self.collection.values()
)
return {
"total_cards": total_cards,
"total_value": total_value,
"unique_cards": len(self.collection)
}
def export_to_dataframe(self):
"""
Export collection to pandas DataFrame
"""
df_data = []
for card_id, card_info in self.collection.items():
card_info["id"] = card_id
df_data.append(card_info)
return pd.DataFrame(df_data)
4. Creating the Dashboard
4.1 Building the Visualization Module
Create dashboard.py to visualize your collection:
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
from collections import Counter
def create_collection_visualization(collection):
"""
Create visualizations for the Pokémon collection
"""
df = collection.export_to_dataframe()
# Set up the plotting style
plt.style.use('seaborn-v0_8')
# Create subplots
fig, axes = plt.subplots(2, 2, figsize=(15, 10))
fig.suptitle('Pokémon Collection Dashboard', fontsize=16)
# 1. Quantity distribution
df['quantity'].hist(ax=axes[0,0], bins=20)
axes[0,0].set_title('Distribution of Card Quantities')
axes[0,0].set_xlabel('Quantity')
# 2. Top 10 most collected cards
top_cards = df.nlargest(10, 'quantity')
axes[0,1].barh(range(len(top_cards)), top_cards['quantity'])
axes[0,1].set_yticks(range(len(top_cards)))
axes[0,1].set_yticklabels(top_cards['name'])
axes[0,1].set_title('Top 10 Most Collected Cards')
# 3. Value distribution
df['value'] = df['quantity'] * df.get('price', 0)
df['value'].hist(ax=axes[1,0], bins=20)
axes[1,0].set_title('Distribution of Card Values')
axes[1,0].set_xlabel('Value ($)')
# 4. Collection summary
summary = collection.get_collection_summary()
axes[1,1].axis('off')
axes[1,1].text(0.1, 0.8, f'Total Cards: {summary["total_cards"]}', fontsize=12)
axes[1,1].text(0.1, 0.6, f'Unique Cards: {summary["unique_cards"]}', fontsize=12)
axes[1,1].text(0.1, 0.4, f'Total Value: ${summary["total_value"]:.2f}', fontsize=12)
axes[1,1].set_title('Collection Summary')
plt.tight_layout()
plt.savefig('pokemon_collection_dashboard.png')
plt.show()
return fig
5. Putting It All Together
5.1 Main Application Script
Create main.py to tie everything together:
from pokemon_api import get_pokemon_cards, get_card_details
from collection_manager import PokemonCollection
from dashboard import create_collection_visualization
import time
def main():
print("Pokémon Collection Tracker v1.0")
# Initialize collection
collection = PokemonCollection()
# Example: Add some cards to the collection
# In a real scenario, you'd fetch these from the API
example_cards = [
("base1-1", "Bulbasaur", 2, 5.50),
("base1-2", "Charmander", 1, 8.25),
("base1-3", "Squirtle", 3, 4.75),
]
for card_id, card_name, quantity, price in example_cards:
collection.add_card(card_id, card_name, quantity, price)
# Display collection summary
summary = collection.get_collection_summary()
print(f"\nCollection Summary:")
print(f"Total Cards: {summary['total_cards']}")
print(f"Unique Cards: {summary['unique_cards']}")
print(f"Total Value: ${summary['total_value']:.2f}")
# Create dashboard
print("\nGenerating dashboard...")
create_collection_visualization(collection)
print("\nDashboard saved as 'pokemon_collection_dashboard.png'")
# Optional: Fetch real data from API
print("\nFetching real data from Pokémon TCG API...")
# Get cards from a specific set
cards_data = get_pokemon_cards(set_name="Base Set", page=1, page_size=50)
if cards_data:
print(f"Found {len(cards_data['data'])} cards in Base Set")
# Add first few cards to collection
for i, card in enumerate(cards_data['data'][:5]):
card_id = card['id']
card_name = card['name']
collection.add_card(card_id, card_name, 1)
print("\nUpdated collection with API data")
# Show final summary
final_summary = collection.get_collection_summary()
print(f"\nFinal Collection Summary:")
print(f"Total Cards: {final_summary['total_cards']}")
print(f"Unique Cards: {final_summary['unique_cards']}")
print(f"Total Value: ${final_summary['total_value']:.2f}")
if __name__ == "__main__":
main()
6. Running the Application
6.1 Execute the Tracker
Run your Pokémon collection tracker:
python main.py
6.2 Understanding the Output
The application will:
- Load your existing collection or create a new one
- Display a summary of your collection
- Generate a dashboard visualization
- Fetch real data from the Pokémon TCG API
- Update your collection with new cards
Summary
In this tutorial, you've built a comprehensive Pokémon card collection tracking system that combines API data fetching, web scraping for pricing information, and data visualization. The system allows you to monitor your collection, track card values, and visualize your progress over time. This project demonstrates intermediate-level Python skills including API integration, data manipulation with pandas, and creating visual dashboards with matplotlib and seaborn.
The modular approach makes it easy to extend with additional features like price alerts, trading functionality, or integration with online marketplaces. You can also modify the code to track other collectible card games or expand the dashboard with more sophisticated visualizations.



