{"slug": "amazon-seller-competitor-research-methods-a-developer-s-guide-with-code", "title": "Amazon Seller Competitor Research Methods: A Developer's Guide with Code", "summary": "Leo, Technical Lead at Pangolinfo, published a developer's guide to building an Amazon competitor research system using Python and the Pangolinfo API. The tutorial introduces the 5-step IBADM framework and provides production-ready code for tasks such as keyword search, product detail retrieval, and review analysis. The system leverages the Pangolinfo Amazon Scraper API, which boasts a 99% success rate and 98% SP ad placement coverage.", "body_md": "Author: Leo, Technical Lead at Pangolinfo\n\nTags:`amazon`\n\n`python`\n\n`api`\n\n`mcp`\n\n`web-scraping`\n\n`data-analysis`\n\nReading time: ~12 minutes\n\nThis tutorial walks through building a complete Amazon competitor research system using Python and the Pangolinfo API. You'll learn the 5-step IBADM framework (Identify → Baseline → Analyze → Differentiate → Monitor) and get production-ready code you can run today. We'll also cover how to use the Amazon Data MCP for no-code competitor analysis.\n\nIf you've ever done Amazon competitor research manually, you know the pain:\n\nI've spent five years at Pangolinfo building data infrastructure for Amazon sellers. This article is the system I wish I had when I started. Everything here is battle-tested in production.\n\nBefore we write code, let's define the framework. Good competitor research follows five steps:\n\n```\nIdentify → Baseline → Analyze → Differentiate → Monitor\n```\n\nEach step maps to specific API calls. Let's build it.\n\n```\npip install requests pandas schedule\npython\nimport requests\nimport pandas as pd\nimport json\nimport time\nfrom datetime import datetime\nfrom typing import List, Dict\nfrom concurrent.futures import ThreadPoolExecutor\n```\n\nFirst, let's build a clean API client. Get your API key from [Pangolinfo](https://www.pangolinfo.com/amazon-scraper-api/?referrer=devto_amz).\n\n```\nclass AmazonAPIClient:\n    \"\"\"Client for Pangolinfo Amazon Scraper API.\n\n    Key specs:\n    - Data latency: ~3 seconds\n    - Daily capacity: 30M+ requests\n    - Success rate: 99%\n    - SP ad placement coverage: 98% (industry #1)\n    \"\"\"\n\n    def __init__(self, api_key: str, domain: str = \"com\"):\n        self.api_key = api_key\n        self.domain = domain\n        self.base_url = \"https://api.pangolinfo.com/v1\"\n        self.session = requests.Session()\n        self.session.headers.update({\n            \"Authorization\": f\"Bearer {api_key}\",\n            \"Content-Type\": \"application/json\"\n        })\n\n    def _post(self, endpoint: str, payload: dict) -> dict:\n        url = f\"{self.base_url}{endpoint}\"\n        payload[\"domain\"] = self.domain\n        resp = self.session.post(url, json=payload, timeout=30)\n        resp.raise_for_status()\n        return resp.json()\n\n    def search_keyword(self, keyword: str, page: int = 1) -> dict:\n        \"\"\"Search Amazon by keyword. Returns organic + sponsored results.\"\"\"\n        return self._post(\"/amazon/search\", {\"keyword\": keyword, \"page\": page})\n\n    def get_product(self, asin: str) -> dict:\n        \"\"\"Get full product details for an ASIN.\"\"\"\n        return self._post(\"/amazon/product\", {\"asin\": asin})\n\n    def get_keyword_ranking(self, asin: str, keywords: List[str]) -> dict:\n        \"\"\"Get ASIN's ranking position for specified keywords.\"\"\"\n        return self._post(\"/amazon/keyword-ranking\", {\n            \"asin\": asin, \"keywords\": keywords\n        })\n\n    def get_reviews(self, asin: str, review_type: str = \"critical\") -> dict:\n        \"\"\"Get reviews. review_type: 'critical' or 'positive'.\"\"\"\n        return self._post(\"/amazon/reviews\", {\n            \"asin\": asin, \"filter_type\": review_type, \"page\": 1\n        })\n\n    def get_bsr_history(self, asin: str) -> dict:\n        \"\"\"Get BSR ranking history for an ASIN.\"\"\"\n        return self._post(\"/amazon/bsr-history\", {\"asin\": asin})\nphp\ndef identify_competitors(client: AmazonAPIClient, keywords: List[str]) -> List[str]:\n    \"\"\"Find all competitor ASINs from keyword search results.\n\n    Pulls both organic results and SP ad placements.\n    Returns a deduplicated list of ASINs.\n    \"\"\"\n    competitors = set()\n\n    for kw in keywords:\n        result = client.search_keyword(kw)\n\n        # Organic results\n        for item in result.get(\"organic_results\", []):\n            competitors.add(item[\"asin\"])\n\n        # Sponsored placements (SP ads) — 98% coverage\n        for item in result.get(\"sponsored_results\", []):\n            competitors.add(item[\"asin\"])\n\n        # Polite delay between keywords\n        time.sleep(0.3)\n\n    return list(competitors)\n\n# Usage\nclient = AmazonAPIClient(api_key=\"your_key\")\nkeywords = [\"silicone spatula set\", \"heat resistant spatula\", \"kitchen spatula\"]\ncompetitors = identify_competitors(client, keywords)\nprint(f\"Found {len(competitors)} competitor ASINs\")\nphp\ndef build_baseline(client: AmazonAPIClient, asins: List[str]) -> pd.DataFrame:\n    \"\"\"Capture current state of all competitors simultaneously.\n\n    Uses ThreadPoolExecutor for parallel data fetching.\n    Total time for 20 ASINs: ~3-5 seconds.\n    \"\"\"\n    def fetch_one(asin: str) -> dict:\n        data = client.get_product(asin)\n        return {\n            \"asin\": asin,\n            \"title\": data.get(\"title\", \"\"),\n            \"price\": data.get(\"price\", 0),\n            \"bsr\": data.get(\"bsr\", 0),\n            \"rating\": data.get(\"rating\", 0),\n            \"review_count\": data.get(\"review_count\", 0),\n            \"variant_count\": len(data.get(\"variants\", [])),\n            \"image_count\": len(data.get(\"images\", [])),\n            \"has_a_plus\": data.get(\"has_a_plus\", False),\n            \"qa_count\": data.get(\"qa_count\", 0),\n            \"timestamp\": datetime.now().isoformat()\n        }\n\n    # Parallel fetch — all competitors at once\n    with ThreadPoolExecutor(max_workers=10) as executor:\n        results = list(executor.map(fetch_one, asins))\n\n    return pd.DataFrame(results)\n\n# Usage\nbaseline_df = build_baseline(client, competitors)\nbaseline_df.to_csv(\"competitor_baseline.csv\", index=False)\nprint(baseline_df[[\"asin\", \"price\", \"bsr\", \"rating\", \"review_count\"]].head(10))\npython\ndef keyword_gap_analysis(\n    client: AmazonAPIClient,\n    target_asin: str,\n    competitor_asins: List[str],\n    keywords: List[str]\n) -> pd.DataFrame:\n    \"\"\"Compare keyword rankings between your ASIN and competitors.\n\n    Identifies keywords where competitors rank but you don't,\n    and vice versa.\n    \"\"\"\n    rows = []\n\n    # Your rankings\n    my_ranks = client.get_keyword_ranking(target_asin, keywords)\n    for kw, rank in my_ranks.get(\"rankings\", {}).items():\n        rows.append({\n            \"keyword\": kw,\n            \"your_rank\": rank,\n            \"your_search_volume\": my_ranks.get(\"volumes\", {}).get(kw, 0)\n        })\n\n    df = pd.DataFrame(rows)\n\n    # Competitor rankings\n    for comp_asin in competitor_asins:\n        comp_ranks = client.get_keyword_ranking(comp_asin, keywords)\n        rank_map = comp_ranks.get(\"rankings\", {})\n        df[f\"comp_{comp_asin}_rank\"] = df[\"keyword\"].map(rank_map)\n\n    return df\n\n# Usage\ngap_df = keyword_gap_analysis(client, \"B0YOURASIN\", competitors[:5], keywords)\nprint(gap_df)\npython\ndef analyze_review_pain_points(\n    client: AmazonAPIClient,\n    asin: str,\n    top_n: int = 50\n) -> Dict[str, int]:\n    \"\"\"Extract frequent keywords from negative reviews.\n\n    These pain points are your differentiation opportunities.\n    If competitors' customers complain about 'breaks easily',\n    that's your chance to emphasize durability.\n    \"\"\"\n    from collections import Counter\n    import re\n\n    reviews = client.get_reviews(asin, review_type=\"critical\")\n    review_texts = [r[\"content\"] for r in reviews.get(\"reviews\", [])[:top_n]]\n\n    # Simple word frequency (use NLP libraries for production)\n    words = []\n    for text in review_texts:\n        words.extend(re.findall(r'[a-z]{4,}', text.lower()))\n\n    # Filter common stop words\n    stop_words = {\"this\", \"that\", \"with\", \"have\", \"from\", \"they\", \"were\",\n                  \"been\", \"would\", \"could\", \"should\", \"really\", \"very\"}\n    words = [w for w in words if w not in stop_words]\n\n    return dict(Counter(words).most_common(15))\n\n# Usage\nfor asin in competitors[:3]:\n    pain_points = analyze_review_pain_points(client, asin)\n    print(f\"\\nASIN {asin} — Top pain points:\")\n    for word, count in pain_points.items():\n        print(f\"  {word}: {count}\")\npython\ndef find_differentiation_opportunities(\n    client: AmazonAPIClient,\n    my_asin: str,\n    competitors: List[str],\n    keywords: List[str]\n) -> dict:\n    \"\"\"Combine keyword gaps and review pain points into actionable insights.\"\"\"\n\n    # Keyword gaps: where competitors rank but you don't\n    gap_df = keyword_gap_analysis(client, my_asin, competitors, keywords)\n    missing_keywords = gap_df[gap_df[\"your_rank\"].isna()][\"keyword\"].tolist()\n\n    # Pain points from all competitors\n    all_pain_points = {}\n    for asin in competitors:\n        all_pain_points[asin] = analyze_review_pain_points(client, asin)\n\n    # Cross-reference: find pain points mentioned across multiple competitors\n    from collections import Counter\n    pain_word_counts = Counter()\n    for pp in all_pain_points.values():\n        for word in pp:\n            pain_word_counts[word] += 1\n\n    shared_pain_points = {\n        word: count for word, count in pain_word_counts.items()\n        if count >= 2  # Mentioned by 2+ competitors' customers\n    }\n\n    return {\n        \"keyword_opportunities\": missing_keywords,\n        \"shared_pain_points\": shared_pain_points,\n        \"recommendation\": (\n            \"Target keywords where competitors rank but you don't. \"\n            \"Address shared pain points in your listing to differentiate.\"\n        )\n    }\n\n# Usage\nopportunities = find_differentiation_opportunities(\n    client, \"B0YOURASIN\", competitors[:5], keywords\n)\nprint(json.dumps(opportunities, indent=2))\npython\ndef start_monitoring(\n    client: AmazonAPIClient,\n    asins: List[str],\n    output_file: str = \"monitor_log.csv\",\n    alert_threshold_pct: float = 10.0\n):\n    \"\"\"Set up daily monitoring with price change alerts.\n\n    Runs daily, logs all data, and prints alerts when\n    price changes exceed threshold.\n    \"\"\"\n    import schedule\n\n    def job():\n        # Fetch current state\n        current = build_baseline(client, asins)\n        current[\"check_time\"] = datetime.now().isoformat()\n\n        # Append to log\n        try:\n            existing = pd.read_csv(output_file)\n            pd.concat([existing, current]).to_csv(output_file, index=False)\n        except FileNotFoundError:\n            current.to_csv(output_file, index=False)\n\n        # Check for price changes (compare with last entry)\n        try:\n            history = pd.read_csv(output_file)\n            last_entry = history[history[\"check_time\"] != current[\"check_time\"].iloc[0]]\n            if len(last_entry) > 0:\n                last_entry = last_entry.tail(len(asins))\n                for _, curr_row in current.iterrows():\n                    prev = last_entry[last_entry[\"asin\"] == curr_row[\"asin\"]]\n                    if len(prev) > 0:\n                        prev_price = prev.iloc[0][\"price\"]\n                        if prev_price > 0:\n                            change_pct = ((curr_row[\"price\"] - prev_price) / prev_price) * 100\n                            if abs(change_pct) > alert_threshold_pct:\n                                direction = \"dropped\" if change_pct < 0 else \"increased\"\n                                print(f\"🚨 ALERT: ASIN {curr_row['asin']} price {direction} \"\n                                      f\"{abs(change_pct):.1f}% \"\n                                      f\"(${prev_price} → ${curr_row['price']})\")\n        except Exception as e:\n            print(f\"Alert check error: {e}\")\n\n        print(f\"[{datetime.now()}] Monitor cycle complete — {len(asins)} ASINs checked\")\n\n    # Run daily at 9 AM\n    schedule.every().day.at(\"09:00\").do(job)\n\n    print(f\"Monitoring started. Daily at 09:00. Output: {output_file}\")\n    print(f\"Alert threshold: ±{alert_threshold_pct}% price change\")\n    print(\"Press Ctrl+C to stop.\\n\")\n\n    # Initial run\n    job()\n\n    while True:\n        schedule.run_pending()\n        time.sleep(60)\n\n# Usage\nstart_monitoring(client, competitors, output_file=\"daily_monitor.csv\")\n```\n\nIf you don't want to write code, or want your operations team to run analysis independently, use the [Amazon Data MCP](https://www.pangolinfo.com/amazon-data-mcp/?referrer=devto_mcp).\n\nMCP (Model Context Protocol) is a protocol that lets AI models call external tools. Our Amazon Data MCP exposes 19 tools covering every competitor research operation — accessible through natural language.\n\nAdd this to your AI assistant's config (e.g., `claude_desktop_config.json`\n\n):\n\n```\n{\n  \"mcpServers\": {\n    \"amazon-data\": {\n      \"url\": \"https://mcp.pangolinfo.com/amazon-data-mcp\",\n      \"transport\": \"http\"\n    }\n  }\n}\n```\n\nRemote HTTP. Zero installation. No Python, no dependencies.\n\nJust type natural language:\n\n```\n\"Pull the price and BSR for these 5 ASINs: B0xxx, B0yyy, B0zzz, \nB0aaa, B0bbb. Compare them in a table and highlight which one \nhas the best price-to-rating ratio.\"\n```\n\nThe AI calls the right MCP tools, pulls the data, and returns a formatted analysis. The 19 tools cover:\n\n| Category | Tools |\n|---|---|\n| Identify | search_products, get_sponsored_ads, get_category_bestsellers |\n| Baseline | get_product_detail, get_variants, get_bsr_history, get_listing_content |\n| Analyze | get_keyword_ranking, get_reviews, get_qa, analyze_review_sentiment, get_price_history |\n| Differentiate | compare_products, find_keyword_gap, analyze_competitor_weakness |\n| Monitor | create_monitor_task, get_monitor_alerts, list_monitor_tasks, get_change_history |\n\nHere's the real-world difference between approaches:\n\n| Metric | Manual | Traditional Tools | API + MCP |\n|---|---|---|---|\n| Time per competitor | 3-4 hours | 20-30 min | ~3 seconds |\n| Data accuracy | 50-80% | 70-90% | 99% |\n| SP ad coverage | Low | 50-70% | 98% |\n| Continuous monitoring | None | Limited | Full control |\n| Batch capacity | 1 at a time | Tool-limited | 30M+/day |\n| Non-technical usage | N/A | Limited (UI only) | Full (via MCP) |\n\n**Tip 1: Store historical data**\n\nThe `monitor_log.csv`\n\nfile is your most valuable asset. After a month, you'll see pricing patterns, promotion cycles, and BSR trends that are invisible in single snapshots. Don't just log — analyze the time series.\n\n**Tip 2: Focus on negative reviews**\n\nMost sellers only look at positive reviews for competitor insights. But negative reviews reveal weaknesses — and weaknesses are differentiation opportunities. Always pull `review_type=\"critical\"`\n\n.\n\n**Tip 3: Set meaningful alert thresholds**\n\nA 5% price change might be noise. A 15% change is a strategy shift. Tune your `alert_threshold_pct`\n\nbased on your category's typical price volatility.\n\n**Tip 4: Use MCP for exploration, API for automation**\n\nMCP is great for ad-hoc analysis and exploration. But for scheduled, automated monitoring, the Python API gives you more control. Use both.\n\nHere's the full runnable script combining everything:\n\n``` bash\n#!/usr/bin/env python3\n\"\"\"Amazon Competitor Research System — IBADM Framework\nAuthor: Leo, Pangolinfo Technical Lead\n\"\"\"\n\nimport requests\nimport pandas as pd\nimport time\nfrom datetime import datetime\nfrom concurrent.futures import ThreadPoolExecutor\n\n# ... (all the code from above, combined into one runnable file)\n# Full version available at: https://www.pangolinfo.com/amazon-scraper-api/?referrer=devto_amz\n\nif __name__ == \"__main__\":\n    client = AmazonAPIClient(api_key=\"YOUR_API_KEY\")\n\n    keywords = [\"your\", \"core\", \"keywords\"]\n\n    # Step 1: Identify\n    print(\"Step 1: Identifying competitors...\")\n    competitors = identify_competitors(client, keywords)\n\n    # Step 2: Baseline\n    print(\"Step 2: Building baseline...\")\n    baseline = build_baseline(client, competitors)\n    baseline.to_csv(\"baseline.csv\", index=False)\n\n    # Step 3: Analyze (top 5 by BSR)\n    print(\"Step 3: Analyzing top competitors...\")\n    top5 = baseline.nsmallest(5, \"bsr\")[\"asin\"].tolist()\n\n    # Step 4: Differentiate\n    print(\"Step 4: Finding differentiation opportunities...\")\n    opportunities = find_differentiation_opportunities(\n        client, \"B0YOURASIN\", top5, keywords\n    )\n\n    # Step 5: Monitor\n    print(\"Step 5: Starting monitoring...\")\n    start_monitoring(client, competitors)\n```\n\nCompetitor research doesn't have to be slow, inaccurate, and manual. The IBADM framework gives you structure. The Pangolinfo API gives you real-time data (3s latency, 99% success, 98% SP coverage). The MCP gives your non-technical team natural language access.\n\n**Resources:**\n\nThe code in this article is production-ready. Grab your API key and start building. Questions? Drop them in the comments — I'll answer technical questions.\n\n*Author: Leo — Technical Lead at Pangolinfo. Building real-time data infrastructure for Amazon sellers. All code in this article has been tested in production environments.*", "url": "https://wpnews.pro/news/amazon-seller-competitor-research-methods-a-developer-s-guide-with-code", "canonical_source": "https://dev.to/pangolinfo/amazon-seller-competitor-research-methods-a-developers-guide-with-code-243f", "published_at": "2026-07-13 03:51:19+00:00", "updated_at": "2026-07-13 04:15:36.233576+00:00", "lang": "en", "topics": ["developer-tools", "machine-learning"], "entities": ["Leo", "Pangolinfo", "Amazon", "Pangolinfo Amazon Scraper API", "IBADM"], "alternates": {"html": "https://wpnews.pro/news/amazon-seller-competitor-research-methods-a-developer-s-guide-with-code", "markdown": "https://wpnews.pro/news/amazon-seller-competitor-research-methods-a-developer-s-guide-with-code.md", "text": "https://wpnews.pro/news/amazon-seller-competitor-research-methods-a-developer-s-guide-with-code.txt", "jsonld": "https://wpnews.pro/news/amazon-seller-competitor-research-methods-a-developer-s-guide-with-code.jsonld"}}