ProductHunt is where new products launch. Tracking launches, upvotes, and maker activity gives you an early signal on market trends, competitor moves, and emerging opportunities. Here's how to build a competitive intelligence pipeline from ProductHunt data.
What Intelligence Can You Extract?
- New product launches in your category
- Upvote velocity (how fast a product gains traction)
- Maker activity and serial entrepreneurs
- Comment sentiment and user feedback
- Technology trends and emerging categories
Scraping ProductHunt Launches
import requests
from bs4 import BeautifulSoup
import json
import time
from datetime import datetime
class ProductHuntScraper:
BASE_URL = "https://www.producthunt.com"
def __init__(self):
self.session = requests.Session()
self.session.headers.update({
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)',
'Accept': 'text/html,application/xhtml+xml',
})
def get_daily_launches(self, date=None):
"""Get products launched on a specific date."""
if date:
url = f"{self.BASE_URL}/leaderboard/daily/{date}"
else:
url = f"{self.BASE_URL}/leaderboard/daily"
resp = self.session.get(url)
soup = BeautifulSoup(resp.text, 'html.parser')
# Extract product data from the page
products = []
items = soup.select('[data-test="post-item"]')
for item in items:
name_el = item.select_one('[data-test="post-name"]')
tagline_el = item.select_one('[data-test="post-tagline"]')
votes_el = item.select_one('[data-test="vote-button"]')
products.append({
'name': name_el.get_text(strip=True) if name_el else '',
'tagline': tagline_el.get_text(strip=True) if tagline_el else '',
'votes': self._parse_votes(votes_el),
'date': date or datetime.now().strftime('%Y-%m-%d'),
})
return products
def _parse_votes(self, element):
if not element:
return 0
text = element.get_text(strip=True)
try:
return int(text.replace(',', ''))
except ValueError:
return 0
def get_product_details(self, product_url):
"""Get detailed info for a specific product."""
resp = self.session.get(product_url)
soup = BeautifulSoup(resp.text, 'html.parser')
description = soup.select_one('[data-test="product-description"]')
topics = [t.get_text(strip=True) for t in soup.select('[data-test="topic-tag"]')]
makers = [m.get_text(strip=True) for m in soup.select('[data-test="maker-name"]')]
return {
'description': description.get_text(strip=True) if description else '',
'topics': topics,
'makers': makers,
}
Building a Competitive Dashboard
import pandas as pd
class CompetitiveIntelligence:
def __init__(self, scraper):
self.scraper = scraper
self.data = []
def track_category(self, keywords, days=30):
"""Track launches matching keywords over time."""
from datetime import timedelta
for i in range(days):
date = (datetime.now() - timedelta(days=i)).strftime('%Y/%m/%d')
launches = self.scraper.get_daily_launches(date)
for product in launches:
# Check if product matches our keywords
text = f"{product['name']} {product['tagline']}".lower()
if any(kw.lower() in text for kw in keywords):
product['matched_keywords'] = [
kw for kw in keywords if kw.lower() in text
]
self.data.append(product)
time.sleep(2)
df = pd.DataFrame(self.data)
print(f"Found {len(df)} matching products in {days} days")
return df
def analyze_trends(self, df):
"""Identify trends from tracked launches."""
if df.empty:
return {}
# Most common themes
all_keywords = []
for kws in df['matched_keywords']:
all_keywords.extend(kws)
from collections import Counter
keyword_freq = Counter(all_keywords)
# Average votes by keyword
df_exploded = df.explode('matched_keywords')
avg_votes = df_exploded.groupby('matched_keywords')['votes'].mean()
print("Category trends:")
for kw, count in keyword_freq.most_common(10):
avg = avg_votes.get(kw, 0)
print(f" {kw}: {count} launches, avg {avg:.0f} upvotes")
return {'frequency': keyword_freq, 'avg_votes': avg_votes}
# Example: Track AI tool launches
scraper = ProductHuntScraper()
ci = CompetitiveIntelligence(scraper)
ai_launches = ci.track_category(
['AI', 'GPT', 'LLM', 'automation', 'agent'],
days=14
)
ci.analyze_trends(ai_launches)
Launch Velocity Tracking
def track_launch_velocity(scraper, product_url, check_interval=300, duration=3600):
"""Track upvote velocity for a specific launch."""
snapshots = []
start_time = time.time()
while time.time() - start_time < duration:
# Re-fetch the page to get updated vote count
resp = scraper.session.get(product_url)
soup = BeautifulSoup(resp.text, 'html.parser')
votes_el = soup.select_one('[data-test="vote-button"]')
votes = scraper._parse_votes(votes_el)
snapshots.append({
'timestamp': datetime.now().isoformat(),
'votes': votes,
})
print(f" {votes} votes at {datetime.now().strftime('%H:%M')}")
time.sleep(check_interval)
df = pd.DataFrame(snapshots)
df['votes_per_hour'] = df['votes'].diff() * (3600 / check_interval)
print(f"\nPeak velocity: {df['votes_per_hour'].max():.0f} votes/hour")
return df
Scaling ProductHunt Intelligence
For continuous, automated competitive monitoring, the ProductHunt Scraper on Apify runs on a schedule and delivers structured data to your analytics pipeline without manual intervention.
For proxy management during web data collection, ScraperAPI handles the infrastructure so you can focus on analysis.
Conclusion
ProductHunt data is a leading indicator for tech market trends. By tracking launches, upvote velocity, and category activity, you can spot competitors early, validate product ideas, and understand where the market is heading. Start with the Python scraper above, build category tracking, and scale to automated monitoring for continuous intelligence.
Top comments (0)