Library · Marketing, sales and analytics with AI

AI competitive intelligence: automatic market monitoring with Claude

Builder60 minUpdated: October 2026
70 of 105 in the library

Time: about 25 min theory + 35 min practice


The gist

🎨 Picture this: military intelligence never stops. While the commander sleeps, scouts watch the other side's positions, record every move and every change, and in the morning they put a briefing on the desk. In business, this kind of "intelligence" used to be an analyst's job: 3 days of collecting data by hand, a spreadsheet, a summary report once a quarter. By then the competitor had already raised prices, shipped a feature and repositioned its website. Now an automated system does it overnight, and in the morning a ready briefing is waiting for you in your messenger or inbox.

In this lesson you'll build exactly that kind of system: you'll set up automatic competitor monitoring and launch a weekly AI report.


Key concepts

  • Competitive intelligence: systematically collecting and analyzing data about what competitors do, so you can make strategic decisions
  • Ahrefs MCP: an integration that brings Ahrefs SEO (search engine optimization) data into Claude so you can analyze competitors' organic traffic and keywords
  • Playwright: a Microsoft library for browser automation; it lets you scrape data from any website
  • ChangeDetection.io: a service that monitors changes on web pages and sends notifications
  • SimilarWeb API (API: application programming interface): data on competitors' audiences, traffic sources and visitor demographics
  • Price scraping: automatically collecting competitors' prices on a regular schedule
  • Differential analysis: a "before / after" comparison to spot strategic changes
  • Data synthesis: when Claude turns scattered facts into a coherent strategic report

Theory

Competitive intelligence: what changed with AI

Before AI, competitive analysis was a once-a-quarter ritual. You hire an intern or an analyst, they spend a week digging through websites, exporting data from Semrush and building a spreadsheet. You look at it and realize the data is already stale: the competitor launched a new feature yesterday.

The architecture is different now:

  • Data is collected automatically (Playwright, ChangeDetection, APIs)
  • Updates happen daily or weekly, with no human involved
  • Analysis is instant, through Claude
  • Delivery goes to your messenger (Telegram, Slack) or email on Monday morning

It's not just faster. It's a different class of tool: you see the market as it is now, not a snapshot of last quarter.


What to monitor: a map of competitor watching

Not everything matters equally. Here's what to track, in order of priority:

Signal What it means Tool
Price changes The competitor is testing a new monetization model Playwright scraping
New pages on the site They're entering a new niche or launching a feature ChangeDetection.io
Growth in organic traffic They've found an SEO strategy that works Ahrefs MCP / Semrush
New keywords What they're betting on in their content Ahrefs / SpyFu
Homepage changes Product repositioning or a new value prop ChangeDetection.io
Job openings Where they're investing (hiring developers means a product is coming) The careers page on the competitor's site (ChangeDetection.io), LinkedIn by hand
Customer reviews Weak spots (complaints = your opportunities) G2, Capterra, App Store

🎨 Picture this: a chess player looks at the whole board, not just their own pieces. Competitive intelligence is your view of the other side of the board. See where their pieces are moving, and you understand their plan 3 moves ahead.


Ahrefs MCP: SEO data right inside Claude

Ahrefs is a leading SEO tool that shows a website's organic traffic, the keywords it ranks for and where its links come from. An MCP (Model Context Protocol) integration lets you request this data right through Claude without switching between tools. Both Ahrefs and Semrush offer an MCP connection; availability depends on your plan, so check your account with the service.

What you can ask through Ahrefs MCP:

  • How much organic traffic does competitor.com get?
  • Which keywords are they in Google's top 3 for?
  • Which pages bring them the most traffic?
  • Which new keywords have they started ranking for in the last month?

A practical example of a request in Claude with Ahrefs MCP:

Type this into the chat
Use Ahrefs MCP to analyze the competitor [URL].

I need:
1. Total organic traffic for the last 3 months (the trend)
2. Top 10 pages by traffic
3. Keywords in positions 4-10 (opportunity keywords, almost in the top)
4. New keywords from the last 30 days

Based on the analysis:
- What's working for the competitor in SEO?
- Which keywords should I go after?
- Are there content topics they've missed?

Without MCP: an alternative through the Ahrefs API:

python
import requests
import anthropic
import json
from datetime import date

def get_ahrefs_data(domain: str, api_key: str) -> dict:
    """Gets the main SEO metrics for a domain through Ahrefs API v3.
    The API is available on paid plans. Check required parameters and limits at docs.ahrefs.com:
    the parameter set for endpoints changes."""
    
    headers = {"Authorization": f"Bearer {api_key}"}
    base = "https://api.ahrefs.com/v3"
    
    # Organic metrics
    metrics_resp = requests.get(
        f"{base}/site-explorer/metrics",
        headers=headers,
        params={"target": domain, "mode": "domain", "date": date.today().isoformat()}
    )
    
    # Top pages
    pages_resp = requests.get(
        f"{base}/site-explorer/top-pages",
        headers=headers,
        params={"target": domain, "mode": "domain", "limit": 10}
    )
    
    return {
        "metrics": metrics_resp.json() if metrics_resp.ok else {},
        "top_pages": pages_resp.json() if pages_resp.ok else {}
    }

# Analysis with Claude
client = anthropic.Anthropic()

competitors = ["competitor1.com", "competitor2.com", "competitor3.com"]
# AHREFS_API_KEY = os.getenv("AHREFS_API_KEY")

# For demonstration: the data structure you'll get:
demo_data = {
    "competitor1.com": {
        "organic_traffic": 45200,
        "organic_keywords": 3840,
        "top_pages": [
            {"url": "/blog/ai-automation-guide", "traffic": 8400},
            {"url": "/pricing", "traffic": 4200},
        ]
    }
}

message = client.messages.create(
    model="claude-sonnet-5-5",
    max_tokens=1500,
    messages=[{
        "role": "user",
        "content": f"""Analyze the competitors' SEO data:

{json.dumps(demo_data, ensure_ascii=False, indent=2)}

My site is [your domain], the niche is AI tools for small businesses.

Answer:
1. Who leads in organic search and why?
2. Which topics/pages generate the most traffic?
3. Which keywords should I go after first?
4. What are competitors missing (content gaps)?"""
    }]
)
print("".join(b.text for b in message.content if b.type == "text"))

Playwright: scraping any website

Playwright is a Microsoft library for browser automation. Unlike simple HTTP requests, Playwright launches a real browser, so it works even with sites that render through JavaScript (React, Vue, Next.js).

Installation:

bash
pip install playwright
playwright install chromium

Scraping competitors' prices:

python
import asyncio
from playwright.async_api import async_playwright
import json
from datetime import datetime

async def scrape_pricing_page(url: str) -> dict:
    """Scrapes a competitor's pricing page"""
    
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)
        page = await browser.new_page()
        
        # Identify as a regular browser; we don't bypass the site's protection
        await page.set_extra_http_headers({
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"
        })
        
        await page.goto(url, wait_until="networkidle", timeout=30000)
        
        # Extract the page text
        content = await page.inner_text("body")
        
        # Look for prices with JavaScript
        prices = await page.evaluate("""
            () => {
                const priceElements = document.querySelectorAll('[class*="price"], [class*="plan"], [class*="tier"]');
                return Array.from(priceElements).map(el => el.innerText.trim()).filter(t => t.length > 0);
            }
        """)
        
        await browser.close()
        
        return {
            "url": url,
            "scraped_at": datetime.now().isoformat(),
            "page_text": content[:5000],  # first 5000 characters
            "price_elements": prices[:20]
        }

async def monitor_competitors(competitor_urls: list) -> list:
    """Monitors a list of competitors in parallel"""
    tasks = [scrape_pricing_page(url) for url in competitor_urls]
    results = await asyncio.gather(*tasks, return_exceptions=True)
    
    return [r for r in results if not isinstance(r, Exception)]

# Run
competitors_pricing = [
    "https://competitor1.com/pricing",
    "https://competitor2.com/plans",
]

results = asyncio.run(monitor_competitors(competitors_pricing))

# Save with the date (for differential analysis)
filename = f"competitor_data_{datetime.now().strftime('%Y-%m-%d')}.json"
with open(filename, 'w', encoding='utf-8') as f:
    json.dump(results, f, ensure_ascii=False, indent=2)

print(f"Data saved: {filename}")

Scraping and the rules. Collect only public pages, read the site's robots.txt and terms of use, don't bypass bot protection and don't create unnecessary load: once a week is enough for monitoring. If you need one or two pages without writing your own code, Firecrawl works (it returns the page as clean markdown).

Differential analysis (what changed):

python
import json
from datetime import datetime, timedelta

def find_changes(old_file: str, new_file: str) -> dict:
    """Compares two snapshots of competitor data"""
    
    with open(old_file) as f:
        old_data = json.load(f)
    with open(new_file) as f:
        new_data = json.load(f)
    
    changes = []
    
    old_by_url = {r['url']: r for r in old_data}
    new_by_url = {r['url']: r for r in new_data}
    
    for url in new_by_url:
        if url in old_by_url:
            old_text = old_by_url[url].get('page_text', '')
            new_text = new_by_url[url].get('page_text', '')
            
            # Simple comparison; in production use difflib
            if old_text != new_text:
                changes.append({
                    "url": url,
                    "change_detected": True,
                    "old_length": len(old_text),
                    "new_length": len(new_text),
                    "delta": len(new_text) - len(old_text)
                })
    
    return changes

ChangeDetection.io: monitoring without code

For pages that don't need complex parsing, ChangeDetection.io is simpler and more reliable than writing your own scraper.

How to set it up:

  1. Sign up at changedetection.io (the self-hosted version is free, the cloud version is paid; prices are on the site)
  2. Add the competitor's URL
  3. Specify which elements to track (you can use a CSS selector)
  4. Set up a notification: email or webhook

Webhook → n8n → Claude → Telegram:

Code
ChangeDetection.io detected a change
→ Webhook POST to n8n
→ n8n: a request to Claude with the "before" and "after" text
→ Claude analyzes: what changed strategically?
→ A Telegram notification to you with the analysis

Telegram here is just one option; the last step can just as well be Slack or email.

An example n8n workflow (see the n8n and AI workflows lesson) with an extra Claude step:

Type this into the chat
System prompt for Claude in n8n:
You are a competitive intelligence analyst.
A competitor changed a page on their website.

Here's what it was:
{old_content}

Here's what it is now:
{new_content}

Analyze:
1. What exactly changed (be specific)?
2. What does it say strategically?
3. Do we need to respond, and how?

Be brief: 3-5 sentences.

SimilarWeb API: competitors' audiences

SimilarWeb shows what Ahrefs doesn't: traffic sources (not just organic, but also paid ads, direct, referral), audience geography, demographics and behavior.

What's important to know:

  • The official API is designed for business accounts and is expensive (pricing on request)
  • To monitor a small number of competitors, the free SimilarWeb browser extension is enough (pull the data by hand once a month)
  • Unofficial wrappers do show up in API marketplaces, but check their terms and data quality yourself

What you actually need to know about a competitor from SimilarWeb:

  • % of traffic from search vs. direct vs. social media (direct traffic = a loyal audience)
  • Top referral traffic sources (partnerships and mentions that work)
  • Average session duration (audience engagement)
  • The countries with the largest audience

The full pipeline: a weekly intelligence report

Here's the architecture of the system you'll build:

Code
[MONDAY 06:00 — automatically]
    │
    ├─ Playwright scraper: collects data on competitors' prices
    ├─ ChangeDetection: checks the sites for changes
    └─ Ahrefs API: exports SEO metrics
    │
    ▼
[Claude analysis]
    Combines all the data
    Compares it with last week
    Writes a report with conclusions
    │
    ▼
[Telegram bot — 08:00]
    📊 Weekly competitor report
    Competitor 1: no changes
    Competitor 2: ⚠️ Price cut from $49 → $39
    Competitor 3: 🆕 New page /ai-assistant
    
    Claude's analysis: [strategic conclusions]

Script: an automatic weekly report

The script delivers the report through a Telegram bot. If you prefer Slack or email, ask Claude Code to swap the send_telegram function for the channel you use.

python
import asyncio
import anthropic
import json
import os
from datetime import datetime
from playwright.async_api import async_playwright
import requests

ANTHROPIC_API_KEY = os.getenv("ANTHROPIC_API_KEY")
TELEGRAM_TOKEN = os.getenv("TELEGRAM_TOKEN")
TELEGRAM_CHAT_ID = os.getenv("TELEGRAM_CHAT_ID")

COMPETITORS = [
    {
        "name": "Competitor A",
        "pricing_url": "https://competitorA.com/pricing",
        "homepage": "https://competitorA.com"
    },
    {
        "name": "Competitor B",
        "pricing_url": "https://competitorB.com/plans",
        "homepage": "https://competitorB.com"
    },
]

async def scrape_page_text(url: str) -> str:
    """Returns the text content of a page"""
    try:
        async with async_playwright() as p:
            browser = await p.chromium.launch(headless=True)
            page = await browser.new_page()
            await page.goto(url, wait_until="domcontentloaded", timeout=20000)
            text = await page.inner_text("body")
            await browser.close()
            return text[:8000]
    except Exception as e:
        return f"Scraping error {url}: {e}"

def load_previous_data(filename: str) -> dict:
    try:
        with open(filename) as f:
            return json.load(f)
    except FileNotFoundError:
        return {}

def save_current_data(data: dict, filename: str):
    with open(filename, 'w', encoding='utf-8') as f:
        json.dump(data, f, ensure_ascii=False, indent=2)

def send_telegram(message: str):
    url = f"https://api.telegram.org/bot{TELEGRAM_TOKEN}/sendMessage"
    requests.post(url, json={
        "chat_id": TELEGRAM_CHAT_ID,
        "text": message,
        "parse_mode": "Markdown"
    })

async def generate_weekly_report():
    print(f"Starting data collection: {datetime.now()}")
    
    # Load last week's data
    prev_data = load_previous_data("competitor_snapshot.json")
    current_data = {}
    
    # Scrape all competitors
    for competitor in COMPETITORS:
        print(f"  Scraping {competitor['name']}...")
        pricing_text = await scrape_page_text(competitor['pricing_url'])
        homepage_text = await scrape_page_text(competitor['homepage'])
        
        current_data[competitor['name']] = {
            "scraped_at": datetime.now().isoformat(),
            "pricing": pricing_text,
            "homepage": homepage_text
        }
    
    # Save the current snapshot
    save_current_data(current_data, "competitor_snapshot.json")
    
    # Build the context for Claude
    analysis_input = []
    for name, data in current_data.items():
        prev = prev_data.get(name, {})
        analysis_input.append({
            "competitor": name,
            "current_pricing": data['pricing'][:2000],
            "current_homepage": data['homepage'][:1000],
            "previous_pricing": prev.get('pricing', 'No data')[:2000],
            "change_detected": data['pricing'] != prev.get('pricing', '')
        })
    
    # Analysis with Claude
    client = anthropic.Anthropic(api_key=ANTHROPIC_API_KEY)
    
    message = client.messages.create(
        model="claude-sonnet-5-5",
        max_tokens=1500,
        messages=[{
            "role": "user",
            "content": f"""This is a weekly competitive intelligence report.

Competitor data (this week vs. last week):
{json.dumps(analysis_input, ensure_ascii=False, indent=2)}

Write a short (up to 500 words) report for Telegram with emoji:
1. 🔍 What changed for each competitor
2. ⚠️ Important signals that call for a response from us
3. 💡 One strategic recommendation for this week

If nothing changed, say so plainly too."""
        }]
    )
    
    report = "".join(b.text for b in message.content if b.type == "text")
    
    # Send to Telegram
    header = f"📊 *Weekly intelligence* — {datetime.now().strftime('%m/%d/%Y')}\n\n"
    send_telegram(header + report)
    
    print("Report sent to Telegram")

# Run
asyncio.run(generate_weekly_report())

Automating with cron (run every Monday at 06:00):

bash
# crontab -e
0 6 * * 1 cd /path/to/project && python competitive_monitor.py >> logs/ci_$(date +\%Y\%m\%d).log 2>&1

Practice

Task: set up monitoring for 3 competitors with a weekly report


Step 1: Prepare the environment (5 minutes)

bash
mkdir competitive-intel && cd competitive-intel
python3 -m venv venv && source venv/bin/activate
pip install playwright anthropic python-dotenv requests
playwright install chromium

# Create a .env file:
# ANTHROPIC_API_KEY=sk-ant-...
# TELEGRAM_TOKEN=...
# TELEGRAM_CHAT_ID=...

Step 2: The first manual snapshot (10 minutes)

Create first_snapshot.py using the generate_weekly_report() script from the theory section.

Run it by hand to get a baseline snapshot:

bash
python first_snapshot.py

Check that competitor_snapshot.json was created with real competitor data.


Step 3: Set up ChangeDetection.io (5 minutes)

  1. Deploy changedetection.io yourself (the self-hosted version is free) or use the cloud version
  2. Add the URLs of all three competitors' pricing pages
  3. Turn on email or webhook notifications
  4. Set the check schedule: every 24 hours

Now any change on the page sends you a notification without running any scripts.


Step 4: Test a manual analysis with Claude (10 minutes)

python
# test_analysis.py
import anthropic
import json

client = anthropic.Anthropic()

# Load the collected data
with open('competitor_snapshot.json') as f:
    data = json.load(f)

# Format it for Claude
summary = ""
for name, info in data.items():
    summary += f"\n### {name}\n"
    summary += f"Pricing page (first 500 characters):\n{info['pricing'][:500]}\n"

message = client.messages.create(
    model="claude-sonnet-5-5",
    max_tokens=1000,
    messages=[{
        "role": "user",
        "content": f"""Here's data from competitors' websites:

{summary}

Tell me:
1. What pricing model does each one use?
2. Who is the cheapest, who is the most expensive?
3. What looks strongest in their offer?
4. What weak spots do you see?"""
    }]
)

print("".join(b.text for b in message.content if b.type == "text"))

Step 5: Set up automatic runs (5 minutes)

On a Mac, use launchd or just cron:

bash
# Open crontab
crontab -e

# Add a line (every Monday at 07:00)
0 7 * * 1 /Users/you/competitive-intel/venv/bin/python /Users/you/competitive-intel/competitive_monitor.py

On a VPS, it's the same line in the user's crontab.

Alternative: run it through an n8n Schedule Trigger (the n8n and AI workflows lesson). No server setup, just a node with a schedule.


Tools and resources

  • Playwright: browser automation for scraping, free (Microsoft)
  • ChangeDetection.io: change monitoring, free self-hosted, paid cloud version
  • Ahrefs: competitors' SEO data; there's a free Ahrefs tier for checking your own site, and paid plan prices and API terms are on the site
  • Semrush: an alternative to Ahrefs, with a trial period
  • SpyFu: an alternative focused on PPC data (paid)
  • SimilarWeb: audience and traffic, a free browser extension for basic data
  • Anthropic API: Claude for synthesizing and analyzing data; model names in the lesson's code are as of October 2026, current prices and versions: What's current
  • G2 / Capterra: reviews from competitors' customers (a gold mine of their weaknesses)

Key takeaways

"Competitive intelligence used to cost 3 days of an analyst's time. Now it's a 100-line script and Claude. But the value isn't in the data: the value is in acting on that data before a competitor has locked in their position."

"The best find in competitive analysis isn't what they do well, it's what they do badly. Reviews from competitors' customers are literally a list of features you could build to win over their audience."

"An automatic weekly report isn't a luxury. It's hygiene. The market changes every week, and a weekly look helps you notice changes while you can still respond calmly."


Next lesson

→ CRM on autopilot: HubSpot + AI

We move from watching the market to your own sales: how Claude fills in customer records, scores leads and writes follow-ups.

The mark stays in this browser only and is never sent anywhere. My progress