Skill: marlowne12/clickbank-scraper (version 1.0.0)

--- name: clickbank-scraper description: > Scrape top ClickBank products by category with gravity scores, commission rates, and estimated monthly sales. Integrates with affiliate marketing automation pipelines for Pinterest board generation and pin content creation. Part of Max's ClickBank affiliate marketing automation suite. --- # ClickBank Product Scraper Autonomous scraper for high-performing ClickBank products. Pulls product metadata (gravity, commission, sales estimates) from CBTrends.com and exports structured JSON for pipeline integration. ## Installation ```bash npm install ``` **Dependencies:** - `cheerio` — HTML parsing - `node-fetch` — HTTP requests - `node` ≥ v16 ## Usage ### Basic Run ```bash node scraper.js ``` Outputs to `output/latest.json`, `output/products-YYYY-MM-DD.json` ### With ClickBank Affiliate ID ```bash CB_AFFILIATE_ID=your_nickname node scraper.js ``` Generates hoplinks with your affiliate ID embedded. ### Scheduled Runs Use OpenClaw cron or n8n workflows to run daily: ```json { "job": "clickbank-scraper", "schedule": "0 9 * * *", "command": "CB_AFFILIATE_ID=your_id node scraper.js" } ``` ## Output Format ### latest.json Always-current snapshot for real-time pipeline feeds. ```json { "category": "Health & Fitness", "updatedAt": "2026-03-27T14:00:00Z", "products": [ { "name": "Product Name", "vendorId": "vendor123", "gravity": 87.5, "avgSaleAmount": "$47.00", "commissionPct": 75, "rebillPct": 30, "hoplink": "https://yourname.clickbank.net/...", "estimatedMonthlySales": "$12000" } ] } ``` ### products-YYYY-MM-DD.json Full daily archive for historical analysis. ### top10-YYYY-MM-DD.json Filtered to gravity > 50 for quick high-performers reference. ## Integration Use Cases ### 1. Pinterest Board Automation Feed `latest.json` → n8n workflow → Auto-generate Pinterest pins for top 10 products ### 2. Product Comparison Content Extract gravity + commission → Generate comparison tables for blog posts ### 3. Affiliate Performance Tracking Monitor gravity trends over time → Pivot to rising winners ### 4. Landing Page Personalization Cross-reference user interests → Recommend high-gravity products ## Data Fields Reference | Field | Type | Description | |-------|------|-------------| | name | string | Product name | | vendorId | string | ClickBank vendor identifier | | gravity | number | Affiliate gravity (higher = more demand, 0-100+) | | avgSaleAmount | string | Average transaction value | | commissionPct | number | Commission rate (0-100%) | | rebillPct | number | Rebill/recurring commission % | | hoplink | string | Ready-to-use affiliate link | | estimatedMonthlySales | string | Rough sales estimate | ## Limitations - Single page per category (10 products) from CBTrends - Gravity data may lag 1-2 hours behind ClickBank live marketplace - No API key required (scrapes public data) - Categories limited to: Health & Fitness, Supplements, E-Business, Self-Help ## Roadmap - [x] Health & Fitness category scraper - [ ] Multi-category support (Supplements, Self-Help, E-Business, Investing) - [ ] Pagination (pages 2-5 for 50+ products) - [ ] ClickBank Marketplace API integration (when account active) - [ ] Scheduled runs via cron - [ ] Gravity trend tracking over time - [ ] Email digest of top gainers/losers ## Integration with n8n Example n8n workflow node: ```javascript // n8n "Execute Command" node const exec = require('child_process').execSync; const result = exec('CB_AFFILIATE_ID=your_id node scraper.js', { cwd: '/path/to/clickbank-scraper' }); return JSON.parse(result.toString()); ``` ## Integration with OpenClaw Use as a cron job or sub-agent: ```bash openclaw cron add clickbank-scraper \ --schedule "0 9 * * *" \ --command "cd path/to/scraper && node scraper.js" ``` ## Author Max @ max-co.digital — Autonomous ClickBank affiliate marketing automation. ## License Proprietary — Part of Digital Helper Agency / max-co product suite.

path: output/latest.json
content: {
  "scrapedAt": "2026-03-10T21:26:27.107Z",
  "totalProducts": 10,
  "top10": [
    {
      "name": "Exipure",
      "vendorId": "exipure",
      "category": "Health & Fitness",
      "gravity": 1156.08,
      "popularityRank": 1,
      "avgSaleAmount": 146.124,
      "salePct": 79,
      "commissionPct": 75,
      "referredPct": 98,
      "rebillPct": 43,
      "rebillAmount": 37.57,
      "estimatedMonthlySales": "50,000+",
      "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=exipure",
      "source": "cbtrends",
      "scrapedAt": "2026-03-10T21:26:27.100Z"
    },
    {
      "name": "Java Burn",
      "vendorId": "javaburn",
      "category": "Health & Fitness",
      "gravity": 535.437,
      "popularityRank": 2,
      "avgSaleAmount": 117.417,
      "salePct": 76,
      "commissionPct": 75,
      "referredPct": 100,
      "rebillPct": 8,
      "rebillAmount": 2.53,
      "estimatedMonthlySales": "50,000+",
      "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=javaburn",
      "source": "cbtrends",
      "scrapedAt": "2026-03-10T21:26:27.105Z"
    },
    {
      "name": "The Smoothie Diet: 21 Day Rapid Weight Loss Program",
      "vendorId": "smoothdiet",
      "category": "Health & Fitness",
      "gravity": 258.524,
      "popularityRank": 9,
      "avgSaleAmount": 28.7175,
      "salePct": 75,
      "commissionPct": 75,
      "referredPct": 92,
      "rebillPct": 1,
      "rebillAmount": 0,
      "estimatedMonthlySales": "10,000-50,000",
      "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=smoothdiet",
      "source": "cbtrends",
      "scrapedAt": "2026-03-10T21:26:27.105Z"
    },
    {
      "name": "Dentitox - Unique Dental Drops Offer",
      "vendorId": "dentitox",
      "category": "Health & Fitness",
      "gravity": 229.23,
      "popularityRank": 3,
      "avgSaleAmount": 105.146,
      "salePct": 63,
      "commissionPct": 65,
      "referredPct": 95,
      "rebillPct": 1,
      "rebillAmount": 0,
      "estimatedMonthlySales": "10,000-50,000",
      "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=dentitox",
      "source": "cbtrends",
      "scrapedAt": "2026-03-10T21:26:27.105Z"
    },
    {
      "name": "Glucofort - Leading Blood Sugar Support",
      "vendorId": "gluco4",
      "category": "Health & Fitness",
      "gravity": 199.26,
      "popularityRank": 4,
      "avgSaleAmount": 146.988,
      "salePct": 65,
      "commissionPct": 70,
      "referredPct": 98,
      "rebillPct": 1,
      "rebillAmount": 0,
      "estimatedMonthlySales": "5,000-10,000",
      "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=gluco4",
      "source": "cbtrends",
      "scrapedAt": "2026-03-10T21:26:27.105Z"
    },
    {
      "name": "Tea Burn - New!!",
      "vendorId": "teaburn",
      "category": "Health & Fitness",
      "gravity": 192.057,
      "popularityRank": 6,
      "avgSaleAmount": 123.784,
      "salePct": 79,
      "commissionPct": 75,
      "referredPct": 100,
      "rebillPct": 100,
      "rebillAmount": 30.36,
      "estimatedMonthlySales": "5,000-10,000",
      "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=teaburn",
      "source": "cbtrends",
      "scrapedAt": "2026-03-10T21:26:27.105Z"
    },
    {
      "name": "Custom Keto Diet",
      "vendorId": "1keto",
      "category": "Health & Fitness",
      "gravity": 174.419,
      "popularityRank": 19,
      "avgSaleAmount": 31.4887,
      "salePct": 68,
      "commissionPct": 75,
      "referredPct": 81,
      "rebillPct": 74,
      "rebillAmount": 20.45,
      "estimatedMonthlySales": "5,000-10,000",
      "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=1keto",
      "source": "cbtrends",
      "scrapedAt": "2026-03-10T21:26:27.105Z"
    },
    {
      "name": "Glucotrust",
      "vendorId": "glucotrust",
      "category": "Health & Fitness",
      "gravity": 171.148,
      "popularityRank": 5,
      "avgSaleAmount": 149.932,
      "salePct": 69,
      "commissionPct": 70,
      "referredPct": 97,
      "rebillPct": 1,
      "rebillAmount": 0,
      "estimatedMonthlySales": "5,000-10,000",
      "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=glucotrust",
      "source": "cbtrends",
      "scrapedAt": "2026-03-10T21:26:27.105Z"
    },
    {
      "name": "Okinawa Flat Belly Tonic",
      "vendorId": "fbtonic",
      "category": "Health & Fitness",
      "gravity": 169.083,
      "popularityRank": 7,
      "avgSaleAmount": 129.829,
      "salePct": 74,
      "commissionPct": 75,
      "referredPct": 97,
      "rebillPct": 1,
      "rebillAmount": 0,
      "estimatedMonthlySales": "5,000-10,000",
      "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=fbtonic",
      "source": "cbtrends",
      "scrapedAt": "2026-03-10T21:26:27.105Z"
    },
    {
      "name": "Altai Balance - Get 85% Revshare Or Cpa!",
      "vendorId": "altaiblood",
      "category": "Health & Fitness",
      "gravity": 128.989,
      "popularityRank": 8,
      "avgSaleAmount": 115.796,
      "salePct": 81,
      "commissionPct": 75,
      "referredPct": 98,
      "rebillPct": 1,
      "rebillAmount": 0,
      "estimatedMonthlySales": "5,000-10,000",
      "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=altaiblood",
      "source": "cbtrends",
      "scrapedAt": "2026-03-10T21:26:27.105Z"
    }
  ],
  "allProducts": [
    {
      "name": "Exipure",
      "vendorId": "exipure",
      "category": "Health & Fitness",
      "gravity": 1156.08,
      "popularityRank": 1,
      "avgSaleAmount": 146.124,
      "salePct": 79,
      "commissionPct": 75,
      "referredPct": 98,
      "rebillPct": 43,
      "rebillAmount": 37.57,
      "estimatedMonthlySales": "50,000+",
      "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=exipure",
      "source": "cbtrends",
      "scrapedAt": "2026-03-10T21:26:27.100Z"
    },
    {
      "name": "Java Burn",
      "vendorId": "javaburn",
      "category": "Health & Fitness",
      "gravity": 535.437,
      "popularityRank": 2,
      "avgSaleAmount": 117.417,
      "salePct": 76,
      "commissionPct": 75,
      "referredPct": 100,
      "rebillPct": 8,
      "rebillAmount": 2.53,
      "estimatedMonthlySales": "50,000+",
      "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=javaburn",
      "source": "cbtrends",
      "scrapedAt": "2026-03-10T21:26:27.105Z"
    },
    {
      "name": "The Smoothie Diet: 21 Day Rapid Weight Loss Program",
      "vendorId": "smoothdiet",
      "category": "Health & Fitness",
      "gravity": 258.524,
      "popularityRank": 9,
      "avgSaleAmount": 28.7175,
      "salePct": 75,
      "commissionPct": 75,
      "referredPct": 92,
      "rebillPct": 1,
      "rebillAmount": 0,
      "estimatedMonthlySales": "10,000-50,000",
      "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=smoothdiet",
      "source": "cbtrends",
      "scrapedAt": "2026-03-10T21:26:27.105Z"
    },
    {
      "name": "Dentitox - Unique Dental Drops Offer",
      "vendorId": "dentitox",
      "category": "Health & Fitness",
      "gravity": 229.23,
      "popularityRank": 3,
      "avgSaleAmount": 105.146,
      "salePct": 63,
      "commissionPct": 65,
      "referredPct": 95,
      "rebillPct": 1,
      "rebillAmount": 0,
      "estimatedMonthlySales": "10,000-50,000",
      "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=dentitox",
      "source": "cbtrends",
      "scrapedAt": "2026-03-10T21:26:27.105Z"
    },
    {
      "name": "Glucofort - Leading Blood Sugar Support",
      "vendorId": "gluco4",
      "category": "Health & Fitness",
      "gravity": 199.26,
      "popularityRank": 4,
      "avgSaleAmount": 146.988,
      "salePct": 65,
      "commissionPct": 70,
      "referredPct": 98,
      "rebillPct": 1,
      "rebillAmount": 0,
      "estimatedMonthlySales": "5,000-10,000",
      "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=gluco4",
      "source": "cbtrends",
      "scrapedAt": "2026-03-10T21:26:27.105Z"
    },
    {
      "name": "Tea Burn - New!!",
      "vendorId": "teaburn",
      "category": "Health & Fitness",
      "gravity": 192.057,
      "popularityRank": 6,
      "avgSaleAmount": 123.784,
      "salePct": 79,
      "commissionPct": 75,
      "referredPct": 100,
      "rebillPct": 100,
      "rebillAmount": 30.36,
      "estimatedMonthlySales": "5,000-10,000",
      "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=teaburn",
      "source": "cbtrends",
      "scrapedAt": "2026-03-10T21:26:27.105Z"
    },
    {
      "name": "Custom Keto Diet",
      "vendorId": "1keto",
      "category": "Health & Fitness",
      "gravity": 174.419,
      "popularityRank": 19,
      "avgSaleAmount": 31.4887,
      "salePct": 68,
      "commissionPct": 75,
      "referredPct": 81,
      "rebillPct": 74,
      "rebillAmount": 20.45,
      "estimatedMonthlySales": "5,000-10,000",
      "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=1keto",
      "source": "cbtrends",
      "scrapedAt": "2026-03-10T21:26:27.105Z"
    },
    {
      "name": "Glucotrust",
      "vendorId": "glucotrust",
      "category": "Health & Fitness",
      "gravity": 171.148,
      "popularityRank": 5,
      "avgSaleAmount": 149.932,
      "salePct": 69,
      "commissionPct": 70,
      "referredPct": 97,
      "rebillPct": 1,
      "rebillAmount": 0,
      "estimatedMonthlySales": "5,000-10,000",
      "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=glucotrust",
      "source": "cbtrends",
      "scrapedAt": "2026-03-10T21:26:27.105Z"
    },
    {
      "name": "Okinawa Flat Belly Tonic",
      "vendorId": "fbtonic",
      "category": "Health & Fitness",
      "gravity": 169.083,
      "popularityRank": 7,
      "avgSaleAmount": 129.829,
      "salePct": 74,
      "commissionPct": 75,
      "referredPct": 97,
      "rebillPct": 1,
      "rebillAmount": 0,
      "estimatedMonthlySales": "5,000-10,000",
      "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=fbtonic",
      "source": "cbtrends",
      "scrapedAt": "2026-03-10T21:26:27.105Z"
    },
    {
      "name": "Altai Balance - Get 85% Revshare Or Cpa!",
      "vendorId": "altaiblood",
      "category": "Health & Fitness",
      "gravity": 128.989,
      "popularityRank": 8,
      "avgSaleAmount": 115.796,
      "salePct": 81,
      "commissionPct": 75,
      "referredPct": 98,
      "rebillPct": 1,
      "rebillAmount": 0,
      "estimatedMonthlySales": "5,000-10,000",
      "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=altaiblood",
      "source": "cbtrends",
      "scrapedAt": "2026-03-10T21:26:27.105Z"
    }
  ]
}

path: output/products-2026-03-10.json
content: [
  {
    "name": "Exipure",
    "vendorId": "exipure",
    "category": "Health & Fitness",
    "gravity": 1156.08,
    "popularityRank": 1,
    "avgSaleAmount": 146.124,
    "salePct": 79,
    "commissionPct": 75,
    "referredPct": 98,
    "rebillPct": 43,
    "rebillAmount": 37.57,
    "estimatedMonthlySales": "50,000+",
    "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=exipure",
    "source": "cbtrends",
    "scrapedAt": "2026-03-10T21:26:27.100Z"
  },
  {
    "name": "Java Burn",
    "vendorId": "javaburn",
    "category": "Health & Fitness",
    "gravity": 535.437,
    "popularityRank": 2,
    "avgSaleAmount": 117.417,
    "salePct": 76,
    "commissionPct": 75,
    "referredPct": 100,
    "rebillPct": 8,
    "rebillAmount": 2.53,
    "estimatedMonthlySales": "50,000+",
    "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=javaburn",
    "source": "cbtrends",
    "scrapedAt": "2026-03-10T21:26:27.105Z"
  },
  {
    "name": "The Smoothie Diet: 21 Day Rapid Weight Loss Program",
    "vendorId": "smoothdiet",
    "category": "Health & Fitness",
    "gravity": 258.524,
    "popularityRank": 9,
    "avgSaleAmount": 28.7175,
    "salePct": 75,
    "commissionPct": 75,
    "referredPct": 92,
    "rebillPct": 1,
    "rebillAmount": 0,
    "estimatedMonthlySales": "10,000-50,000",
    "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=smoothdiet",
    "source": "cbtrends",
    "scrapedAt": "2026-03-10T21:26:27.105Z"
  },
  {
    "name": "Dentitox - Unique Dental Drops Offer",
    "vendorId": "dentitox",
    "category": "Health & Fitness",
    "gravity": 229.23,
    "popularityRank": 3,
    "avgSaleAmount": 105.146,
    "salePct": 63,
    "commissionPct": 65,
    "referredPct": 95,
    "rebillPct": 1,
    "rebillAmount": 0,
    "estimatedMonthlySales": "10,000-50,000",
    "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=dentitox",
    "source": "cbtrends",
    "scrapedAt": "2026-03-10T21:26:27.105Z"
  },
  {
    "name": "Glucofort - Leading Blood Sugar Support",
    "vendorId": "gluco4",
    "category": "Health & Fitness",
    "gravity": 199.26,
    "popularityRank": 4,
    "avgSaleAmount": 146.988,
    "salePct": 65,
    "commissionPct": 70,
    "referredPct": 98,
    "rebillPct": 1,
    "rebillAmount": 0,
    "estimatedMonthlySales": "5,000-10,000",
    "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=gluco4",
    "source": "cbtrends",
    "scrapedAt": "2026-03-10T21:26:27.105Z"
  },
  {
    "name": "Tea Burn - New!!",
    "vendorId": "teaburn",
    "category": "Health & Fitness",
    "gravity": 192.057,
    "popularityRank": 6,
    "avgSaleAmount": 123.784,
    "salePct": 79,
    "commissionPct": 75,
    "referredPct": 100,
    "rebillPct": 100,
    "rebillAmount": 30.36,
    "estimatedMonthlySales": "5,000-10,000",
    "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=teaburn",
    "source": "cbtrends",
    "scrapedAt": "2026-03-10T21:26:27.105Z"
  },
  {
    "name": "Custom Keto Diet",
    "vendorId": "1keto",
    "category": "Health & Fitness",
    "gravity": 174.419,
    "popularityRank": 19,
    "avgSaleAmount": 31.4887,
    "salePct": 68,
    "commissionPct": 75,
    "referredPct": 81,
    "rebillPct": 74,
    "rebillAmount": 20.45,
    "estimatedMonthlySales": "5,000-10,000",
    "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=1keto",
    "source": "cbtrends",
    "scrapedAt": "2026-03-10T21:26:27.105Z"
  },
  {
    "name": "Glucotrust",
    "vendorId": "glucotrust",
    "category": "Health & Fitness",
    "gravity": 171.148,
    "popularityRank": 5,
    "avgSaleAmount": 149.932,
    "salePct": 69,
    "commissionPct": 70,
    "referredPct": 97,
    "rebillPct": 1,
    "rebillAmount": 0,
    "estimatedMonthlySales": "5,000-10,000",
    "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=glucotrust",
    "source": "cbtrends",
    "scrapedAt": "2026-03-10T21:26:27.105Z"
  },
  {
    "name": "Okinawa Flat Belly Tonic",
    "vendorId": "fbtonic",
    "category": "Health & Fitness",
    "gravity": 169.083,
    "popularityRank": 7,
    "avgSaleAmount": 129.829,
    "salePct": 74,
    "commissionPct": 75,
    "referredPct": 97,
    "rebillPct": 1,
    "rebillAmount": 0,
    "estimatedMonthlySales": "5,000-10,000",
    "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=fbtonic",
    "source": "cbtrends",
    "scrapedAt": "2026-03-10T21:26:27.105Z"
  },
  {
    "name": "Altai Balance - Get 85% Revshare Or Cpa!",
    "vendorId": "altaiblood",
    "category": "Health & Fitness",
    "gravity": 128.989,
    "popularityRank": 8,
    "avgSaleAmount": 115.796,
    "salePct": 81,
    "commissionPct": 75,
    "referredPct": 98,
    "rebillPct": 1,
    "rebillAmount": 0,
    "estimatedMonthlySales": "5,000-10,000",
    "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=altaiblood",
    "source": "cbtrends",
    "scrapedAt": "2026-03-10T21:26:27.105Z"
  }
]

path: output/top10-2026-03-10.json
content: [
  {
    "name": "Exipure",
    "vendorId": "exipure",
    "category": "Health & Fitness",
    "gravity": 1156.08,
    "popularityRank": 1,
    "avgSaleAmount": 146.124,
    "salePct": 79,
    "commissionPct": 75,
    "referredPct": 98,
    "rebillPct": 43,
    "rebillAmount": 37.57,
    "estimatedMonthlySales": "50,000+",
    "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=exipure",
    "source": "cbtrends",
    "scrapedAt": "2026-03-10T21:26:27.100Z"
  },
  {
    "name": "Java Burn",
    "vendorId": "javaburn",
    "category": "Health & Fitness",
    "gravity": 535.437,
    "popularityRank": 2,
    "avgSaleAmount": 117.417,
    "salePct": 76,
    "commissionPct": 75,
    "referredPct": 100,
    "rebillPct": 8,
    "rebillAmount": 2.53,
    "estimatedMonthlySales": "50,000+",
    "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=javaburn",
    "source": "cbtrends",
    "scrapedAt": "2026-03-10T21:26:27.105Z"
  },
  {
    "name": "The Smoothie Diet: 21 Day Rapid Weight Loss Program",
    "vendorId": "smoothdiet",
    "category": "Health & Fitness",
    "gravity": 258.524,
    "popularityRank": 9,
    "avgSaleAmount": 28.7175,
    "salePct": 75,
    "commissionPct": 75,
    "referredPct": 92,
    "rebillPct": 1,
    "rebillAmount": 0,
    "estimatedMonthlySales": "10,000-50,000",
    "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=smoothdiet",
    "source": "cbtrends",
    "scrapedAt": "2026-03-10T21:26:27.105Z"
  },
  {
    "name": "Dentitox - Unique Dental Drops Offer",
    "vendorId": "dentitox",
    "category": "Health & Fitness",
    "gravity": 229.23,
    "popularityRank": 3,
    "avgSaleAmount": 105.146,
    "salePct": 63,
    "commissionPct": 65,
    "referredPct": 95,
    "rebillPct": 1,
    "rebillAmount": 0,
    "estimatedMonthlySales": "10,000-50,000",
    "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=dentitox",
    "source": "cbtrends",
    "scrapedAt": "2026-03-10T21:26:27.105Z"
  },
  {
    "name": "Glucofort - Leading Blood Sugar Support",
    "vendorId": "gluco4",
    "category": "Health & Fitness",
    "gravity": 199.26,
    "popularityRank": 4,
    "avgSaleAmount": 146.988,
    "salePct": 65,
    "commissionPct": 70,
    "referredPct": 98,
    "rebillPct": 1,
    "rebillAmount": 0,
    "estimatedMonthlySales": "5,000-10,000",
    "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=gluco4",
    "source": "cbtrends",
    "scrapedAt": "2026-03-10T21:26:27.105Z"
  },
  {
    "name": "Tea Burn - New!!",
    "vendorId": "teaburn",
    "category": "Health & Fitness",
    "gravity": 192.057,
    "popularityRank": 6,
    "avgSaleAmount": 123.784,
    "salePct": 79,
    "commissionPct": 75,
    "referredPct": 100,
    "rebillPct": 100,
    "rebillAmount": 30.36,
    "estimatedMonthlySales": "5,000-10,000",
    "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=teaburn",
    "source": "cbtrends",
    "scrapedAt": "2026-03-10T21:26:27.105Z"
  },
  {
    "name": "Custom Keto Diet",
    "vendorId": "1keto",
    "category": "Health & Fitness",
    "gravity": 174.419,
    "popularityRank": 19,
    "avgSaleAmount": 31.4887,
    "salePct": 68,
    "commissionPct": 75,
    "referredPct": 81,
    "rebillPct": 74,
    "rebillAmount": 20.45,
    "estimatedMonthlySales": "5,000-10,000",
    "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=1keto",
    "source": "cbtrends",
    "scrapedAt": "2026-03-10T21:26:27.105Z"
  },
  {
    "name": "Glucotrust",
    "vendorId": "glucotrust",
    "category": "Health & Fitness",
    "gravity": 171.148,
    "popularityRank": 5,
    "avgSaleAmount": 149.932,
    "salePct": 69,
    "commissionPct": 70,
    "referredPct": 97,
    "rebillPct": 1,
    "rebillAmount": 0,
    "estimatedMonthlySales": "5,000-10,000",
    "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=glucotrust",
    "source": "cbtrends",
    "scrapedAt": "2026-03-10T21:26:27.105Z"
  },
  {
    "name": "Okinawa Flat Belly Tonic",
    "vendorId": "fbtonic",
    "category": "Health & Fitness",
    "gravity": 169.083,
    "popularityRank": 7,
    "avgSaleAmount": 129.829,
    "salePct": 74,
    "commissionPct": 75,
    "referredPct": 97,
    "rebillPct": 1,
    "rebillAmount": 0,
    "estimatedMonthlySales": "5,000-10,000",
    "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=fbtonic",
    "source": "cbtrends",
    "scrapedAt": "2026-03-10T21:26:27.105Z"
  },
  {
    "name": "Altai Balance - Get 85% Revshare Or Cpa!",
    "vendorId": "altaiblood",
    "category": "Health & Fitness",
    "gravity": 128.989,
    "popularityRank": 8,
    "avgSaleAmount": 115.796,
    "salePct": 81,
    "commissionPct": 75,
    "referredPct": 98,
    "rebillPct": 1,
    "rebillAmount": 0,
    "estimatedMonthlySales": "5,000-10,000",
    "hoplink": "https://hop.clickbank.net/?affiliate=YOUR_CB_NICKNAME&vendor=altaiblood",
    "source": "cbtrends",
    "scrapedAt": "2026-03-10T21:26:27.105Z"
  }
]

path: package-lock.json
content: {
  "name": "clickbank-scraper",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "clickbank-scraper",
      "version": "1.0.0",
      "license": "ISC",
      "dependencies": {
        "cheerio": "^1.2.0",
        "node-fetch": "^2.7.0"
      }
    },
    "node_modules/boolbase": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "ISC"
    },
    "node_modules/cheerio": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "dependencies": {
        "cheerio-select": "^2.1.0",
        "dom-serializer": "^2.0.0",
        "domhandler": "^5.0.3",
        "domutils": "^3.2.2",
        "encoding-sniffer": "^0.2.1",
        "htmlparser2": "^10.1.0",
        "parse5": "^7.3.0",
        "parse5-htmlparser2-tree-adapter": "^7.1.0",
        "parse5-parser-stream": "^7.1.2",
        "undici": "^7.19.0",
        "whatwg-mimetype": "^4.0.0"
      },
      "engines": {
        "node": ">=20.18.1"
      },
      "funding": {
        "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
      }
    },
    "node_modules/cheerio-select": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "BSD-2-Clause",
      "dependencies": {
        "boolbase": "^1.0.0",
        "css-select": "^5.1.0",
        "css-what": "^6.1.0",
        "domelementtype": "^2.3.0",
        "domhandler": "^5.0.3",
        "domutils": "^3.0.1"
      },
      "funding": {
        "url": "https://github.com/sponsors/fb55"
      }
    },
    "node_modules/css-select": {
      "version": "5.2.2",
      "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "BSD-2-Clause",
      "dependencies": {
        "boolbase": "^1.0.0",
        "css-what": "^6.1.0",
        "domhandler": "^5.0.2",
        "domutils": "^3.0.1",
        "nth-check": "^2.0.1"
      },
      "funding": {
        "url": "https://github.com/sponsors/fb55"
      }
    },
    "node_modules/css-what": {
      "version": "6.2.2",
      "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "BSD-2-Clause",
      "engines": {
        "node": ">= 6"
      },
      "funding": {
        "url": "https://github.com/sponsors/fb55"
      }
    },
    "node_modules/dom-serializer": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "dependencies": {
        "domelementtype": "^2.3.0",
        "domhandler": "^5.0.2",
        "entities": "^4.2.0"
      },
      "funding": {
        "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
      }
    },
    "node_modules/domelementtype": {
      "version": "2.3.0",
      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
      "integrity": [REDACTED_SECRET],
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/fb55"
        }
      ],
      "license": "BSD-2-Clause"
    },
    "node_modules/domhandler": {
      "version": "5.0.3",
      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "BSD-2-Clause",
      "dependencies": {
        "domelementtype": "^2.3.0"
      },
      "engines": {
        "node": ">= 4"
      },
      "funding": {
        "url": "https://github.com/fb55/domhandler?sponsor=1"
      }
    },
    "node_modules/domutils": {
      "version": "3.2.2",
      "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "BSD-2-Clause",
      "dependencies": {
        "dom-serializer": "^2.0.0",
        "domelementtype": "^2.3.0",
        "domhandler": "^5.0.3"
      },
      "funding": {
        "url": "https://github.com/fb55/domutils?sponsor=1"
      }
    },
    "node_modules/encoding-sniffer": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "dependencies": {
        "iconv-lite": "^0.6.3",
        "whatwg-encoding": "^3.1.1"
      },
      "funding": {
        "url": "https://github.com/fb55/encoding-sniffer?sponsor=1"
      }
    },
    "node_modules/entities": {
      "version": "4.5.0",
      "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "BSD-2-Clause",
      "engines": {
        "node": ">=0.12"
      },
      "funding": {
        "url": "https://github.com/fb55/entities?sponsor=1"
      }
    },
    "node_modules/htmlparser2": {
      "version": "10.1.0",
      "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz",
      "integrity": [REDACTED_SECRET],
      "funding": [
        "https://github.com/fb55/htmlparser2?sponsor=1",
        {
          "type": "github",
          "url": "https://github.com/sponsors/fb55"
        }
      ],
      "license": "MIT",
      "dependencies": {
        "domelementtype": "^2.3.0",
        "domhandler": "^5.0.3",
        "domutils": "^3.2.2",
        "entities": "^7.0.1"
      }
    },
    "node_modules/htmlparser2/node_modules/entities": {
      "version": "7.0.1",
      "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "BSD-2-Clause",
      "engines": {
        "node": ">=0.12"
      },
      "funding": {
        "url": "https://github.com/fb55/entities?sponsor=1"
      }
    },
    "node_modules/iconv-lite": {
      "version": "0.6.3",
      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "dependencies": {
        "safer-buffer": ">= 2.1.2 < 3.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/node-fetch": {
      "version": "2.7.0",
      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "dependencies": {
        "whatwg-url": "^5.0.0"
      },
      "engines": {
        "node": "4.x || >=6.0.0"
      },
      "peerDependencies": {
        "encoding": "^0.1.0"
      },
      "peerDependenciesMeta": {
        "encoding": {
          "optional": true
        }
      }
    },
    "node_modules/nth-check": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "BSD-2-Clause",
      "dependencies": {
        "boolbase": "^1.0.0"
      },
      "funding": {
        "url": "https://github.com/fb55/nth-check?sponsor=1"
      }
    },
    "node_modules/parse5": {
      "version": "7.3.0",
      "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "dependencies": {
        "entities": "^6.0.0"
      },
      "funding": {
        "url": "https://github.com/inikulin/parse5?sponsor=1"
      }
    },
    "node_modules/parse5-htmlparser2-tree-adapter": {
      "version": "7.1.0",
      "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "dependencies": {
        "domhandler": "^5.0.3",
        "parse5": "^7.0.0"
      },
      "funding": {
        "url": "https://github.com/inikulin/parse5?sponsor=1"
      }
    },
    "node_modules/parse5-parser-stream": {
      "version": "7.1.2",
      "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "dependencies": {
        "parse5": "^7.0.0"
      },
      "funding": {
        "url": "https://github.com/inikulin/parse5?sponsor=1"
      }
    },
    "node_modules/parse5/node_modules/entities": {
      "version": "6.0.1",
      "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "BSD-2-Clause",
      "engines": {
        "node": ">=0.12"
      },
      "funding": {
        "url": "https://github.com/fb55/entities?sponsor=1"
      }
    },
    "node_modules/safer-buffer": {
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT"
    },
    "node_modules/tr46": {
      "version": "0.0.3",
      "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT"
    },
    "node_modules/undici": {
      "version": "7.22.0",
      "resolved": "https://registry.npmjs.org/undici/-/undici-7.22.0.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "engines": {
        "node": ">=20.18.1"
      }
    },
    "node_modules/webidl-conversions": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "BSD-2-Clause"
    },
    "node_modules/whatwg-encoding": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
      "integrity": [REDACTED_SECRET],
      "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation",
      "license": "MIT",
      "dependencies": {
        "iconv-lite": "0.6.3"
      },
      "engines": {
        "node": ">=18"
      }
    },
    "node_modules/whatwg-mimetype": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "engines": {
        "node": ">=18"
      }
    },
    "node_modules/whatwg-url": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "dependencies": {
        "tr46": "~0.0.3",
        "webidl-conversions": "^3.0.0"
      }
    }
  }
}


path: package.json
content: {
  "name": "clickbank-scraper",
  "version": "1.0.0",
  "description": "ClickBank Health & Fitness product scraper for affiliate marketing automation",
  "main": "scraper.js",
  "scripts": {
    "scrape": "node scraper.js",
    "test": "node scraper.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "type": "commonjs",
  "dependencies": {
    "cheerio": "^1.2.0",
    "node-fetch": "^2.7.0"
  }
}


path: README.md
content: # ClickBank Product Scraper

MVP scraper for top ClickBank Health & Fitness products via CBTrends.com.

## Setup
```bash
cd max-co/products/clickbank-scraper
npm install  # cheerio + node-fetch
```

## Usage
```bash
# Basic run (uses default affiliate placeholder)
node scraper.js

# With your ClickBank affiliate ID
CB_AFFILIATE_ID=your_nickname node scraper.js
```

## Output
- `output/latest.json` — Always-current snapshot (for pipeline integration)
- `output/products-YYYY-MM-DD.json` — Full daily archive
- `output/top10-YYYY-MM-DD.json` — Top 10 by gravity

## Data Fields
| Field | Description |
|-------|-------------|
| name | Product name |
| vendorId | ClickBank vendor ID |
| gravity | ClickBank gravity score (higher = more affiliates earning) |
| avgSaleAmount | Average $ per sale |
| commissionPct | Commission percentage |
| rebillPct | Rebill percentage |
| hoplink | Ready-to-use affiliate link |
| estimatedMonthlySales | Rough sales estimate based on gravity |

## Integration
- Feed `latest.json` into Pinterest Trends Dashboard
- Cross-reference gravity scores with Pinterest search trends
- Auto-generate pin content for high-gravity products

## Limitations
- Single page (10 products per category page from CBTrends)
- Gravity data may lag ClickBank's live marketplace
- No ClickBank API key needed (public data scraping)

## Next Steps
- [ ] Add pagination (scrape pages 2-5 for 50 products)
- [ ] Add more categories (Supplements, E-Business, Self-Help)
- [ ] ClickBank marketplace API integration (when account exists)
- [ ] Scheduled runs via cron


path: scraper.js
content: /**
 * ClickBank Product Scraper - MVP
 * Scrapes top Health & Fitness products from CBTrends.com
 */

const cheerio = require('cheerio');
const fs = require('fs');
const path = require('path');

const CONFIG = {
  affiliateId: process.env.CB_AFFILIATE_ID || 'YOUR_CB_NICKNAME',
  sources: [
    {
      name: 'Health & Fitness (by gravity)',
      url: 'https://www.cbtrends.com/browse-clickbank-marketplace/-1/94/Health%2B%2526%2BFitness/1/gravity/',
      category: 'Health & Fitness',
    },
  ],
  outputDir: path.join(__dirname, 'output'),
  userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/131.0.0.0',
};

function makeHoplink(vendorId, affiliateId) {
  return `https://hop.clickbank.net/?affiliate=${affiliateId}&vendor=${vendorId}`;
}

function estimateMonthlySales(gravity) {
  if (gravity > 500) return '50,000+';
  if (gravity > 200) return '10,000-50,000';
  if (gravity > 100) return '5,000-10,000';
  if (gravity > 50) return '1,000-5,000';
  if (gravity > 20) return '500-1,000';
  return '100-500';
}

async function fetchPage(url) {
  const res = await fetch(url, {
    headers: { 'User-Agent': CONFIG.userAgent, 'Accept': 'text/html' }
  });
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  return res.text();
}

function parseCBTrends(html, category) {
  const $ = cheerio.load(html);
  const products = [];

  // Extract product names from get-product links (every other one is a duplicate)
  const productNames = [];
  const productIds = [];
  $('a[href*="get-product"]').each((i, el) => {
    const text = $(el).text().trim();
    if (text.length > 2) {
      productNames.push(text);
      // Get the product ID from href
      const href = $(el).attr('href') || '';
      const idMatch = href.match(/productid=([a-f0-9]+)/);
      if (idMatch) productIds.push(idMatch[1]);
    }
  });

  // Extract vendor IDs from clickbank-product links in the product area
  const vendorIds = [];
  $('a[href*="clickbank-product/"]').each((i, el) => {
    const href = $(el).attr('href') || '';
    const vMatch = href.match(/clickbank-product\/([^.]+)/);
    if (vMatch) vendorIds.push(vMatch[1]);
  });

  // Extract stats from body text
  const bodyText = $('body').text();
  const statRegex = /¤\s*Popularity:\s*(\d+)\s*¤\s*Gravity:\s*([\d.]+)\s*¤\s*\$\/Sale:\s*([\d.]+)\s*¤\s*%\/Sale:\s*([\d.]+)\s*¤\s*Commission:\s*([\d.]+)\s*¤\s*Referred:\s*([\d.]+)\s*¤\s*%\/Rebill:\s*([\d.]+)\s*¤\s*Rebill Amt:\s*([\d.]+)\s*¤/g;

  const stats = [];
  let match;
  while ((match = statRegex.exec(bodyText)) !== null) {
    stats.push({
      popularityRank: parseInt(match[1]),
      gravity: parseFloat(match[2]),
      avgSaleAmount: parseFloat(match[3]),
      salePct: parseFloat(match[4]),
      commissionPct: parseInt(match[5]),
      referredPct: parseFloat(match[6]),
      rebillPct: parseFloat(match[7]),
      rebillAmount: parseFloat(match[8]),
    });
  }

  // Combine: names[i] + stats[i] + vendorIds[i]
  const count = Math.min(productNames.length, stats.length);
  for (let i = 0; i < count; i++) {
    const s = stats[i];
    const vendorId = vendorIds[i] || null;
    products.push({
      name: productNames[i],
      vendorId,
      category,
      gravity: s.gravity,
      popularityRank: s.popularityRank,
      avgSaleAmount: s.avgSaleAmount,
      salePct: s.salePct,
      commissionPct: s.commissionPct,
      referredPct: s.referredPct,
      rebillPct: s.rebillPct,
      rebillAmount: s.rebillAmount,
      estimatedMonthlySales: estimateMonthlySales(s.gravity),
      hoplink: vendorId ? makeHoplink(vendorId, CONFIG.affiliateId) : null,
      source: 'cbtrends',
      scrapedAt: new Date().toISOString(),
    });
  }

  return products;
}

async function main() {
  console.log('╔══════════════════════════════════════════════╗');
  console.log('║  ClickBank Product Scraper - Health/Fitness  ║');
  console.log('╚══════════════════════════════════════════════╝\n');

  if (!fs.existsSync(CONFIG.outputDir)) fs.mkdirSync(CONFIG.outputDir, { recursive: true });

  let allProducts = [];
  for (const source of CONFIG.sources) {
    try {
      console.log(`[Scraper] Fetching: ${source.name}`);
      const html = await fetchPage(source.url);
      const products = parseCBTrends(html, source.category);
      console.log(`[Scraper] Parsed ${products.length} products`);
      allProducts.push(...products);
    } catch (err) {
      console.error(`[Error] ${source.name}: ${err.message}`);
    }
  }

  allProducts.sort((a, b) => b.gravity - a.gravity);
  const top10 = allProducts.slice(0, 10);

  console.log(`\n📊 Results: ${allProducts.length} total, top 10:\n`);
  top10.forEach((p, i) => {
    console.log(`  ${String(i + 1).padStart(2)}. ${p.name}`);
    console.log(`      Gravity: ${p.gravity} | Commission: ${p.commissionPct}% | Avg Sale: $${p.avgSaleAmount}`);
    console.log(`      Est. Sales: ${p.estimatedMonthlySales} | Vendor: ${p.vendorId || 'unknown'}`);
    if (p.hoplink) console.log(`      Hoplink: ${p.hoplink}`);
    console.log();
  });

  const ts = new Date().toISOString().split('T')[0];
  fs.writeFileSync(path.join(CONFIG.outputDir, `products-${ts}.json`), JSON.stringify(allProducts, null, 2));
  fs.writeFileSync(path.join(CONFIG.outputDir, `top10-${ts}.json`), JSON.stringify(top10, null, 2));
  fs.writeFileSync(path.join(CONFIG.outputDir, 'latest.json'), JSON.stringify({
    scrapedAt: new Date().toISOString(), totalProducts: allProducts.length, top10, allProducts
  }, null, 2));

  console.log(`💾 Saved ${allProducts.length} products to ${CONFIG.outputDir}`);
  return { top10, allProducts };
}

if (require.main === module) main().catch(err => { console.error('Fatal:', err); process.exit(1); });
module.exports = { main, parseCBTrends, makeHoplink, CONFIG };


Security scan verdicts — ClawScan: clean | static analysis: suspicious | VirusTotal: clean | SkillSpector: suspicious (HIGH)