{
  "version": "1.0.0",
  "exported_at": "2026-05-31T00:00:00.000Z",
  "project": {
    "name": "Amazon Top Lists Scraper",
    "description": "Best-effort scraper for Amazon top-list pages, inferred from the Octoparse Amazon Top Lists template. Starts at Amazon Best Sellers (https://www.amazon.com/gp/bestsellers/), extracts list/category name, subcategory when available, rank position, title, canonical product URL, image URL, price, rating, and review count. Pagination strategy: click the enabled Amazon Next pagination link and loop until no enabled Next link remains, appending all pages to one CSV. Selectors include several Amazon Best Sellers layout variants. Amazon may block automated browsers with CAPTCHA/bot checks or vary selectors by region/layout.",
    "color": "bg-[#ff9900]",
    "template_id": "ai-generated"
  },
  "blocks": [
    {
      "block_id": "navigate-1",
      "block_type": "process",
      "title": "Navigate",
      "description": "Go to a URL",
      "position_x": 120,
      "position_y": 240,
      "config": {
        "url": "https://www.amazon.com/gp/bestsellers/",
        "color": "bg-[#4589ff]"
      }
    },
    {
      "block_id": "wait-for-page-load-1",
      "block_type": "process",
      "title": "Wait for Page Load",
      "description": "Wait for page to finish loading",
      "position_x": 480,
      "position_y": 240,
      "config": {
        "timeout": 45
      }
    },
    {
      "block_id": "wait-for-element-1",
      "block_type": "process",
      "title": "Wait for Element",
      "description": "Wait until element appears",
      "position_x": 840,
      "position_y": 240,
      "config": {
        "selector": "div[id='gridItemRoot'], [id='gridItemRoot'], .zg-grid-general-faceout, .p13n-sc-uncoverable-faceout, .zg-item-immersion, #zg-ordered-list > li",
        "timeout": 45,
        "visible": true
      }
    },
    {
      "block_id": "structured-export-1",
      "block_type": "process",
      "title": "Structured Export",
      "description": "Export data with custom columns",
      "position_x": 1200,
      "position_y": 240,
      "config": {
        "rowSelector": "div[id='gridItemRoot'], [id='gridItemRoot'], .zg-grid-general-faceout, .p13n-sc-uncoverable-faceout, .zg-item-immersion, #zg-ordered-list > li",
        "fileName": "amazon_top_lists_scraper_suite.csv",
        "saveLocation": "C:\\Users\\theskd\\Documents\\UScraper\\templates",
        "includeHeaders": true,
        "fileMode": "append",
        "columns": [
          {
            "name": "list_name",
            "selector": "(document.querySelector('#zg_banner_text, h1, .zg_selected')?.textContent || document.title.replace(/^Amazon\\.com:\\s*/i, '') || '').trim()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "subcategory",
            "selector": "(function(){ const href=ROW.querySelector('a[href*=\"/dp/\"], a[href*=\"/gp/product/\"]')?.getAttribute('href')||''; const m=href.match(/ref[=_]zg_bs_c_([^_/?#]+)_/); return m ? decodeURIComponent(m[1]).replace(/-/g,' ') : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "rank_position",
            "selector": "(function(){ const badge=ROW.querySelector('.zg-bdg-text, .zg-badge-text, .zg_rankNumber'); const txt=(badge?.textContent||'').trim(); if(txt) return txt.replace(/^#\\s*/,'').replace(/\\.$/,''); const id=(ROW.id||ROW.querySelector('[id^=\"p13n-asin-index-\"]')?.id||''); let m=id.match(/p13n-asin-index-(\\d+)/); if(m) return String(Number(m[1])+1); const href=ROW.querySelector('a[href*=\"/dp/\"], a[href*=\"/gp/product/\"]')?.getAttribute('href')||''; m=href.match(/_sccl_(\\d+)/); if(m) return m[1]; m=href.match(/zg_bs[^/?#]*?(\\d+)(?:[/?#]|$)/); return m ? m[1] : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "title",
            "selector": "(ROW.querySelector('._cDEzb_p13n-sc-css-line-clamp-3_g3dy1, ._cDEzb_p13n-sc-css-line-clamp-4_2q2cc, .p13n-sc-truncate, .zg-item .a-link-normal, a.a-link-normal[href*=\"/dp/\"] span, a.a-link-normal[href*=\"/gp/product/\"] span')?.textContent || ROW.querySelector('img')?.getAttribute('alt') || '').trim()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "product_url",
            "selector": "(function(){ const a=ROW.querySelector('a.a-link-normal[href*=\"/dp/\"], a.a-link-normal[href*=\"/gp/product/\"], a.a-link-normal.aok-block, a[href*=\"/dp/\"]'); if(!a) return ''; const href=new URL(a.getAttribute('href'), location.href).href; const m=href.match(/\\/(?:dp|gp\\/product)\\/([A-Z0-9]{10})/); return m ? (location.origin + '/dp/' + m[1]) : href; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "image_url",
            "selector": "(function(){ const img=ROW.querySelector('img'); return img ? (img.getAttribute('src') || img.getAttribute('data-src') || '') : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "price",
            "selector": ".p13n-sc-price, .a-price .a-offscreen, span.a-color-price",
            "attribute": "text"
          },
          {
            "name": "rating",
            "selector": "i.a-icon-star-small span.a-icon-alt, i.a-icon-star span.a-icon-alt, span.a-icon-alt, .a-icon-alt",
            "attribute": "text"
          },
          {
            "name": "review_count",
            "selector": "(function(){ const els=Array.from(ROW.querySelectorAll('a[href*=\"customerReviews\"], a[href*=\"#customerReviews\"], a[href*=\"/product-reviews/\"], span.a-size-small, a.a-link-normal')); for(const el of els){ const values=[el.getAttribute('aria-label')||'', el.textContent||''].map(s=>s.trim()).filter(Boolean); for(const v of values){ if(/out of 5|stars?|rating is/i.test(v)) continue; let m=v.match(/([0-9][0-9,]*)\\s*(?:ratings?|reviews?)/i); if(m) return m[1]; if(/^[0-9][0-9,]*$/.test(v)) return v; } } return ''; })()",
            "attribute": "text",
            "isJs": true
          }
        ]
      }
    },
    {
      "block_id": "element-exists-1",
      "block_type": "process",
      "title": "Element Exists",
      "description": "Check if element exists",
      "position_x": 1560,
      "position_y": 240,
      "config": {
        "selector": "ul.a-pagination li.a-last:not(.a-disabled) a, .a-pagination .a-last:not(.a-disabled) a"
      }
    },
    {
      "block_id": "click-1",
      "block_type": "process",
      "title": "Click",
      "description": "Click on element",
      "position_x": 1560,
      "position_y": 560,
      "config": {
        "selector": "ul.a-pagination li.a-last:not(.a-disabled) a, .a-pagination .a-last:not(.a-disabled) a",
        "timeout": 15
      }
    },
    {
      "block_id": "wait-for-page-load-2",
      "block_type": "process",
      "title": "Wait for Page Load",
      "description": "Wait for page to finish loading",
      "position_x": 1920,
      "position_y": 560,
      "config": {
        "timeout": 45
      }
    },
    {
      "block_id": "wait-for-element-2",
      "block_type": "process",
      "title": "Wait for Element",
      "description": "Wait until element appears",
      "position_x": 2280,
      "position_y": 560,
      "config": {
        "selector": "div[id='gridItemRoot'], [id='gridItemRoot'], .zg-grid-general-faceout, .p13n-sc-uncoverable-faceout, .zg-item-immersion, #zg-ordered-list > li",
        "timeout": 45,
        "visible": true
      }
    },
    {
      "block_id": "sleep-1",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 2640,
      "position_y": 560,
      "config": {
        "duration": 2
      }
    },
    {
      "block_id": "end-1",
      "block_type": "output",
      "title": "End",
      "description": "Terminate execution flow",
      "position_x": 1560,
      "position_y": 880,
      "config": {}
    }
  ],
  "connections": [
    {
      "from_block_id": "navigate-1",
      "from_connector_id": "right",
      "to_block_id": "wait-for-page-load-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "wait-for-page-load-1",
      "from_connector_id": "right",
      "to_block_id": "wait-for-element-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "wait-for-element-1",
      "from_connector_id": "right",
      "to_block_id": "structured-export-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "structured-export-1",
      "from_connector_id": "right",
      "to_block_id": "element-exists-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-1",
      "from_connector_id": "true",
      "to_block_id": "click-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-1",
      "from_connector_id": "false",
      "to_block_id": "end-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "click-1",
      "from_connector_id": "right",
      "to_block_id": "wait-for-page-load-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "wait-for-page-load-2",
      "from_connector_id": "right",
      "to_block_id": "wait-for-element-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "wait-for-element-2",
      "from_connector_id": "right",
      "to_block_id": "sleep-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "sleep-1",
      "from_connector_id": "right",
      "to_block_id": "structured-export-1",
      "to_connector_id": "left"
    }
  ],
  "canvas_elements": [
    {
      "id": "group-load",
      "element_type": "group",
      "title": "Page Load",
      "color": "#08bdba",
      "position_x": 48,
      "position_y": 136,
      "width": 2840,
      "height": 616,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "navigate-1",
          "wait-for-page-load-1",
          "wait-for-element-1",
          "wait-for-page-load-2",
          "wait-for-element-2",
          "sleep-1"
        ]
      }
    },
    {
      "id": "group-extract",
      "element_type": "group",
      "title": "Data Extraction",
      "color": "#42be65",
      "position_x": 1128,
      "position_y": 136,
      "width": 380,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "structured-export-1"
        ]
      }
    },
    {
      "id": "group-pagination",
      "element_type": "group",
      "title": "Pagination Loop",
      "color": "#ff832b",
      "position_x": 1488,
      "position_y": 136,
      "width": 380,
      "height": 616,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "element-exists-1",
          "click-1"
        ]
      }
    },
    {
      "id": "group-control",
      "element_type": "group",
      "title": "Control Flow",
      "color": "#8d8d8d",
      "position_x": 1488,
      "position_y": 776,
      "width": 380,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "end-1"
        ]
      }
    },
    {
      "id": "note-overview",
      "element_type": "note",
      "title": "Overview",
      "content": "Best-effort scraper for Amazon top-list pages, inferred from the Octoparse Amazon Top Lists template. Starts at Amazon Best Sellers (https://www.amazon.com/gp/bestsellers/), extracts list/category name, subcategory when available, rank position, title, canonical product URL, image URL, price, rating, and review count. Pagination strategy: click the enabled Amazon Next pagination link and loop until no enabled Next link remains, appending all pages to one CSV. Selectors include several Amazon Best Sellers layout variants. Amazon may block automated browsers with CAPTCHA/bot checks or vary selectors by region/layout.",
      "color": "#f1c21b",
      "position_x": 80,
      "position_y": 20,
      "width": 480,
      "height": 160,
      "z_index": 22,
      "data": {}
    },
    {
      "id": "note-block-structured-export-1",
      "element_type": "note",
      "title": "Note: Structured Export",
      "content": "Structured export with JS columns (list_name, subcategory, rank_position, title, product_url). These selectors are fragile — update if the site layout changes.",
      "color": "#ee5396",
      "position_x": 1400,
      "position_y": 220,
      "width": 340,
      "height": 133,
      "z_index": 22,
      "data": {
        "block_id": "structured-export-1"
      }
    },
    {
      "id": "note-block-element-exists-1",
      "element_type": "note",
      "title": "Note: Element Exists",
      "content": "Condition block: checks `ul.a-pagination li.a-last:not(.a-disabled) a, .a-pagination .a-last:not(.a-disabled) a`. True / False branches control which path runs next. Keep enough space between branches so both connector lines are visible.",
      "color": "#ee5396",
      "position_x": 1760,
      "position_y": 220,
      "width": 340,
      "height": 159,
      "z_index": 22,
      "data": {
        "block_id": "element-exists-1"
      }
    }
  ]
}