{
  "version": "1.0.0",
  "exported_at": "2026-06-03T15:15:00.000Z",
  "project": {
    "name": "Amazon Review Scraper for UK",
    "description": "Best-effort Amazon UK review scraper for ASIN B00284AO0C. Because Amazon product-reviews pages were blocked in test runs, this version first scrapes embedded review rows from the accessible product page, using robust JS fallbacks for title/content/review URL/product name, then still attempts full pagination through review pageNumber URLs 1-10 and appends all accessible rows to amazon-review-scraper-for-uk.csv. Amazon may still redirect to sign-in or CAPTCHA.",
    "color": "bg-[#ff9900]",
    "template_id": "ai-generated"
  },
  "blocks": [
    {
      "block_id": "set-window-size-1",
      "block_type": "process",
      "title": "Set Window Size",
      "description": "Set browser window dimensions",
      "position_x": 120,
      "position_y": 220,
      "config": {
        "width": 1920,
        "height": 1080,
        "color": "bg-[#4589ff]"
      }
    },
    {
      "block_id": "navigate-2",
      "block_type": "process",
      "title": "Navigate",
      "description": "Go to a URL",
      "position_x": 456,
      "position_y": 220,
      "config": {
        "url": "https://www.amazon.co.uk/",
        "color": "bg-[#08bdba]",
        "tags": [
          "amazon",
          "cookie-warmup"
        ]
      }
    },
    {
      "block_id": "wait-for-page-load-2",
      "block_type": "process",
      "title": "Wait for Page Load",
      "description": "Wait for page to finish loading",
      "position_x": 792,
      "position_y": 220,
      "config": {
        "timeout": 45
      }
    },
    {
      "block_id": "sleep-3",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 1128,
      "position_y": 220,
      "config": {
        "duration": 3
      }
    },
    {
      "block_id": "element-exists-2",
      "block_type": "process",
      "title": "Element Exists",
      "description": "Check if element exists",
      "position_x": 1464,
      "position_y": 220,
      "config": {
        "selector": "#sp-cc-accept, input[name='accept'], button[name='accept'], input#sp-cc-accept"
      }
    },
    {
      "block_id": "click-1",
      "block_type": "process",
      "title": "Click",
      "description": "Click on element",
      "position_x": 1800,
      "position_y": 520,
      "config": {
        "selector": "#sp-cc-accept, input[name='accept'], button[name='accept'], input#sp-cc-accept",
        "timeout": 10
      }
    },
    {
      "block_id": "sleep-4",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 2136,
      "position_y": 520,
      "config": {
        "duration": 2
      }
    },
    {
      "block_id": "inject-javascript-1",
      "block_type": "process",
      "title": "Inject JavaScript",
      "description": "Execute custom JavaScript",
      "position_x": 2472,
      "position_y": 520,
      "config": {
        "jsCode": "(() => { const oneYear = 60 * 60 * 24 * 365; const rand = () => Math.floor(Math.random() * 9000000 + 1000000); const sid = `${rand()}-${rand()}-${rand()}`; document.cookie = `i18n-prefs=GBP; path=/; max-age=${oneYear}`; document.cookie = `lc-acbuk=en_GB; path=/; max-age=${oneYear}`; document.cookie = `session-id=${sid}; path=/; max-age=${oneYear}`; document.cookie = `session-id-time=2082787201l; path=/; max-age=${oneYear}`; document.cookie = `ubid-acbuk=${sid}; path=/; max-age=${oneYear}`; return true; })();",
        "waitForCompletion": true,
        "timeout": 10
      }
    },
    {
      "block_id": "sleep-5",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 2808,
      "position_y": 520,
      "config": {
        "duration": 2
      }
    },
    {
      "block_id": "navigate-3",
      "block_type": "process",
      "title": "Navigate",
      "description": "Go to a URL",
      "position_x": 3144,
      "position_y": 520,
      "config": {
        "url": "https://www.amazon.co.uk/dp/B00284AO0C",
        "color": "bg-[#08bdba]",
        "tags": [
          "amazon",
          "product-page",
          "fallback"
        ]
      }
    },
    {
      "block_id": "wait-for-page-load-3",
      "block_type": "process",
      "title": "Wait for Page Load",
      "description": "Wait for page to finish loading",
      "position_x": 3480,
      "position_y": 520,
      "config": {
        "timeout": 60
      }
    },
    {
      "block_id": "scroll-1",
      "block_type": "process",
      "title": "Scroll",
      "description": "Scroll the page",
      "position_x": 3816,
      "position_y": 520,
      "config": {
        "direction": "down",
        "amount": 5200
      }
    },
    {
      "block_id": "sleep-6",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 4152,
      "position_y": 520,
      "config": {
        "duration": 4
      }
    },
    {
      "block_id": "element-exists-3",
      "block_type": "process",
      "title": "Element Exists",
      "description": "Check if element exists",
      "position_x": 4488,
      "position_y": 520,
      "config": {
        "selector": "#cm-cr-dp-review-list div[data-hook='review'], div[data-hook='review'], div[id^='customer_review-'], [data-hook='review-body']"
      }
    },
    {
      "block_id": "structured-export-2",
      "block_type": "process",
      "title": "Structured Export",
      "description": "Export data with custom columns",
      "position_x": 4824,
      "position_y": 520,
      "config": {
        "rowSelector": "#cm-cr-dp-review-list div[data-hook='review'], div[data-hook='review'], div[id^='customer_review-']",
        "fileName": "amazon-review-scraper-for-uk.csv",
        "saveLocation": "C:\\Users\\theskd\\Documents\\UScraper\\templates",
        "includeHeaders": true,
        "fileMode": "append",
        "columns": [
          {
            "name": "page_url",
            "selector": "window.location.href",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "asin",
            "selector": "(() => { const m = window.location.href.match(/(?:dp|product-reviews)\\/([A-Z0-9]{10})/i); return m ? m[1] : 'B00284AO0C'; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "brand",
            "selector": "(() => { const direct = document.querySelector('#bylineInfo, [data-hook=\"product-brand\"]')?.textContent?.trim() || ''; return direct.replace(/^Visit the\\s+/i, '').replace(/\\s+Store$/i, '').replace(/^Brand:\\s*/i, '').trim(); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "product_name",
            "selector": "(() => { const sels = ['#productTitle', '#title span', '[data-hook=\"product-link\"]', 'a[data-hook=\"product-link\"]', 'meta[property=\"og:title\"]', 'meta[name=\"title\"]']; for (const s of sels) { const el = document.querySelector(s); const v = el ? (el.getAttribute('content') || el.textContent || '').trim() : ''; if (v && !/Product summary presents key product information/i.test(v)) return v.replace(/\\s+/g, ' '); } return (document.title || '').replace(/\\s*:\\s*Amazon\\.co\\.uk.*$/i, '').replace(/\\s+/g, ' ').trim(); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "product_stars",
            "selector": "(() => document.querySelector('#acrPopover .a-icon-alt, [data-hook=\"rating-out-of-text\"], [data-hook=\"rating-out-of-five\"], .averageStarRatingNumerical, .cr-widget-ACR .a-icon-alt')?.textContent?.trim() || '')()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "rating_count",
            "selector": "(() => document.querySelector('#acrCustomerReviewText, [data-hook=\"total-review-count\"], [data-hook=\"cr-filter-info-review-rating-count\"]')?.textContent?.trim().replace(/\\s+/g, ' ') || '')()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "review_rating",
            "selector": "(() => { const text = ROW.querySelector('[data-hook=\"review-star-rating\"] .a-icon-alt, [data-hook=\"cmps-review-star-rating\"] .a-icon-alt, i.review-rating .a-icon-alt, .review-rating .a-icon-alt')?.textContent?.trim() || ''; const m = text.match(/[0-9]+(?:\\.[0-9]+)?/); return m ? m[0] : text; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "reviewer_name",
            "selector": ".a-profile-name",
            "attribute": "text"
          },
          {
            "name": "review_title",
            "selector": "(() => { const clean = s => (s || '').replace(/\\s+/g, ' ').replace(/^\\s*[0-9.]+\\s*out of\\s*5\\s*stars\\s*/i, '').trim(); const el = ROW.querySelector('[data-hook=\"review-title\"], a.review-title, .review-title'); if (el) { const clone = el.cloneNode(true); clone.querySelectorAll('.a-icon-alt, .a-letter-space').forEach(n => n.remove()); const v = clean(clone.textContent); if (v) return v; } const lines = (ROW.innerText || '').split('\\n').map(x => x.trim()).filter(Boolean); return clean(lines.find(x => !/out of 5 stars|Reviewed in|Verified Purchase|One person|people found|Helpful|Report|Colour|Color|Size|Style|VINE/i.test(x) && x !== (ROW.querySelector('.a-profile-name')?.textContent || '').trim()) || ''); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "review_content",
            "selector": "(() => { const clean = s => (s || '').replace(/\\s+/g, ' ').trim(); const el = ROW.querySelector('[data-hook=\"review-body\"], [data-hook=\"review-collapsed\"], .review-text-content, .review-text'); const direct = clean(el?.innerText || el?.textContent || ''); if (direct) return direct; const titleEl = ROW.querySelector('[data-hook=\"review-title\"], a.review-title, .review-title'); const title = clean(titleEl?.textContent || '').replace(/^\\s*[0-9.]+\\s*out of\\s*5\\s*stars\\s*/i, ''); const reviewer = clean(ROW.querySelector('.a-profile-name')?.textContent || ''); const lines = (ROW.innerText || '').split('\\n').map(clean).filter(Boolean); const candidates = lines.filter(x => x !== reviewer && x !== title && !/out of 5 stars|Reviewed in|Verified Purchase|One person|people found|Helpful|Report|Colour|Color|Size|Style|VINE/i.test(x)); return candidates.slice(title ? 1 : 0).join(' '); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "review_url",
            "selector": "(() => { const a = ROW.querySelector('a[data-hook=\"review-title\"], a.review-title, a[href*=\"/gp/customer-reviews/\"]'); if (a && a.href) return a.href; const id = (ROW.id || '').replace(/^customer_review-/, ''); return id ? `https://www.amazon.co.uk/gp/customer-reviews/${id}/ref=cm_cr_arp_d_rvw_ttl?ie=UTF8` : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "review_images",
            "selector": "(() => Array.from(new Set(Array.from(ROW.querySelectorAll('[data-hook=\"review-image-tile\"] img, img.review-image-tile, .review-image-tile-section img, img[src*=\"m.media-amazon.com/images/I/\"]')).map(img => img.src || img.getAttribute('data-src') || '').filter(src => src && !/\\/S\\/sash\\//.test(src)))) .join(';'))()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "is_verified",
            "selector": "(() => ROW.querySelector('[data-hook=\"avp-badge\"], .review-format-strip [class*=\"badge\"]') ? 'True' : 'False')()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "helpful_count",
            "selector": "(() => { const text = ROW.querySelector('[data-hook=\"helpful-vote-statement\"], .cr-vote-text')?.textContent?.trim() || ''; if (!text) return ''; if (/one person/i.test(text)) return '1'; const m = text.match(/[0-9,]+/); return m ? m[0].replace(/,/g, '') : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "date",
            "selector": "(() => { const text = ROW.querySelector('[data-hook=\"review-date\"], .review-date')?.textContent?.trim() || ''; const m = text.match(/on\\s+(.+)$/i); return m ? m[1].trim() : text; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "country",
            "selector": "(() => { const text = ROW.querySelector('[data-hook=\"review-date\"], .review-date')?.textContent?.trim() || ''; const m = text.match(/Reviewed\\s+in\\s+(.+?)\\s+on/i); return m ? m[1].trim() : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "vine_tag",
            "selector": "(() => Array.from(new Set(Array.from(ROW.querySelectorAll('[data-hook=\"avp-badge\"], [data-hook=\"vine-review-badge\"], .a-color-state')).map(el => el.textContent.trim()).filter(Boolean))).join('; '))()",
            "attribute": "text",
            "isJs": true
          }
        ]
      }
    },
    {
      "block_id": "navigate-1",
      "block_type": "process",
      "title": "Navigate",
      "description": "Go to a URL",
      "position_x": 5160,
      "position_y": 520,
      "config": {
        "urls": [
          "https://www.amazon.co.uk/product-reviews/B00284AO0C?ie=UTF8&reviewerType=all_reviews&sortBy=helpful&pageNumber=1",
          "https://www.amazon.co.uk/product-reviews/B00284AO0C?ie=UTF8&reviewerType=all_reviews&sortBy=helpful&pageNumber=2",
          "https://www.amazon.co.uk/product-reviews/B00284AO0C?ie=UTF8&reviewerType=all_reviews&sortBy=helpful&pageNumber=3",
          "https://www.amazon.co.uk/product-reviews/B00284AO0C?ie=UTF8&reviewerType=all_reviews&sortBy=helpful&pageNumber=4",
          "https://www.amazon.co.uk/product-reviews/B00284AO0C?ie=UTF8&reviewerType=all_reviews&sortBy=helpful&pageNumber=5",
          "https://www.amazon.co.uk/product-reviews/B00284AO0C?ie=UTF8&reviewerType=all_reviews&sortBy=helpful&pageNumber=6",
          "https://www.amazon.co.uk/product-reviews/B00284AO0C?ie=UTF8&reviewerType=all_reviews&sortBy=helpful&pageNumber=7",
          "https://www.amazon.co.uk/product-reviews/B00284AO0C?ie=UTF8&reviewerType=all_reviews&sortBy=helpful&pageNumber=8",
          "https://www.amazon.co.uk/product-reviews/B00284AO0C?ie=UTF8&reviewerType=all_reviews&sortBy=helpful&pageNumber=9",
          "https://www.amazon.co.uk/product-reviews/B00284AO0C?ie=UTF8&reviewerType=all_reviews&sortBy=helpful&pageNumber=10"
        ],
        "color": "bg-[#08bdba]",
        "tags": [
          "amazon",
          "reviews",
          "pagination"
        ]
      }
    },
    {
      "block_id": "wait-for-page-load-1",
      "block_type": "process",
      "title": "Wait for Page Load",
      "description": "Wait for page to finish loading",
      "position_x": 5496,
      "position_y": 520,
      "config": {
        "timeout": 60
      }
    },
    {
      "block_id": "sleep-1",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 5832,
      "position_y": 520,
      "config": {
        "duration": 6
      }
    },
    {
      "block_id": "element-exists-1",
      "block_type": "process",
      "title": "Element Exists",
      "description": "Check if element exists",
      "position_x": 6168,
      "position_y": 520,
      "config": {
        "selector": "div[data-hook='review'], div[id^='customer_review-'], #cm_cr-review_list .review, .review[data-hook], [data-hook='review-body']"
      }
    },
    {
      "block_id": "structured-export-1",
      "block_type": "process",
      "title": "Structured Export",
      "description": "Export data with custom columns",
      "position_x": 6504,
      "position_y": 520,
      "config": {
        "rowSelector": "div[data-hook='review'], div[id^='customer_review-'], #cm_cr-review_list .review",
        "fileName": "amazon-review-scraper-for-uk.csv",
        "saveLocation": "C:\\Users\\theskd\\Documents\\UScraper\\templates",
        "includeHeaders": true,
        "fileMode": "append",
        "columns": [
          {
            "name": "page_url",
            "selector": "window.location.href",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "asin",
            "selector": "(() => { const m = window.location.href.match(/product-reviews\\/([A-Z0-9]{10})/i) || window.location.href.match(/\\/dp\\/([A-Z0-9]{10})/i); return m ? m[1] : 'B00284AO0C'; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "brand",
            "selector": "(() => { const direct = document.querySelector('[data-hook=\"product-brand\"], #bylineInfo')?.textContent?.trim() || ''; if (direct) return direct.replace(/^Visit the\\s+/i, '').replace(/\\s+Store$/i, '').replace(/^Brand:\\s*/i, '').trim(); return ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "product_name",
            "selector": "(() => { const sels = ['[data-hook=\"product-link\"]', 'a[data-hook=\"product-link\"]', '#productTitle', '#title span', 'meta[property=\"og:title\"]', 'meta[name=\"title\"]']; for (const s of sels) { const el = document.querySelector(s); const v = el ? (el.getAttribute('content') || el.textContent || '').trim() : ''; if (v && !/Product summary presents key product information/i.test(v)) return v.replace(/\\s+/g, ' '); } return (document.title || '').replace(/\\s*:\\s*Amazon\\.co\\.uk.*$/i, '').replace(/\\s+/g, ' ').trim(); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "product_stars",
            "selector": "(() => document.querySelector('[data-hook=\"rating-out-of-text\"], [data-hook=\"rating-out-of-five\"], .averageStarRatingNumerical, .cr-widget-ACR .a-icon-alt, #acrPopover .a-icon-alt')?.textContent?.trim() || '')()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "rating_count",
            "selector": "(() => { const el = document.querySelector('[data-hook=\"total-review-count\"], [data-hook=\"cr-filter-info-review-rating-count\"], #filter-info-section .a-size-base, #acrCustomerReviewText'); return el ? el.textContent.trim().replace(/\\s+/g, ' ') : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "review_rating",
            "selector": "(() => { const text = ROW.querySelector('[data-hook=\"review-star-rating\"] .a-icon-alt, [data-hook=\"cmps-review-star-rating\"] .a-icon-alt, i.review-rating .a-icon-alt, .review-rating .a-icon-alt')?.textContent?.trim() || ''; const m = text.match(/[0-9]+(?:\\.[0-9]+)?/); return m ? m[0] : text; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "reviewer_name",
            "selector": ".a-profile-name",
            "attribute": "text"
          },
          {
            "name": "review_title",
            "selector": "(() => { const clean = s => (s || '').replace(/\\s+/g, ' ').replace(/^\\s*[0-9.]+\\s*out of\\s*5\\s*stars\\s*/i, '').trim(); const el = ROW.querySelector('[data-hook=\"review-title\"], a.review-title, .review-title'); if (el) { const clone = el.cloneNode(true); clone.querySelectorAll('.a-icon-alt, .a-letter-space').forEach(n => n.remove()); const v = clean(clone.textContent); if (v) return v; } const lines = (ROW.innerText || '').split('\\n').map(x => x.trim()).filter(Boolean); return clean(lines.find(x => !/out of 5 stars|Reviewed in|Verified Purchase|One person|people found|Helpful|Report|Colour|Color|Size|Style|VINE/i.test(x) && x !== (ROW.querySelector('.a-profile-name')?.textContent || '').trim()) || ''); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "review_content",
            "selector": "(() => { const clean = s => (s || '').replace(/\\s+/g, ' ').trim(); const el = ROW.querySelector('[data-hook=\"review-body\"], [data-hook=\"review-collapsed\"], .review-text-content, .review-text'); const direct = clean(el?.innerText || el?.textContent || ''); if (direct) return direct; const titleEl = ROW.querySelector('[data-hook=\"review-title\"], a.review-title, .review-title'); const title = clean(titleEl?.textContent || '').replace(/^\\s*[0-9.]+\\s*out of\\s*5\\s*stars\\s*/i, ''); const reviewer = clean(ROW.querySelector('.a-profile-name')?.textContent || ''); const lines = (ROW.innerText || '').split('\\n').map(clean).filter(Boolean); const candidates = lines.filter(x => x !== reviewer && x !== title && !/out of 5 stars|Reviewed in|Verified Purchase|One person|people found|Helpful|Report|Colour|Color|Size|Style|VINE/i.test(x)); return candidates.slice(title ? 1 : 0).join(' '); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "review_url",
            "selector": "(() => { const a = ROW.querySelector('a[data-hook=\"review-title\"], a.review-title, a[href*=\"/gp/customer-reviews/\"]'); if (a && a.href) return a.href; const id = (ROW.id || '').replace(/^customer_review-/, ''); return id ? `https://www.amazon.co.uk/gp/customer-reviews/${id}/ref=cm_cr_arp_d_rvw_ttl?ie=UTF8` : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "review_images",
            "selector": "(() => Array.from(new Set(Array.from(ROW.querySelectorAll('[data-hook=\"review-image-tile\"] img, img.review-image-tile, .review-image-tile-section img, img[src*=\"m.media-amazon.com/images/I/\"]')).map(img => img.src || img.getAttribute('data-src') || '').filter(src => src && !/\\/S\\/sash\\//.test(src)))) .join(';'))()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "is_verified",
            "selector": "(() => ROW.querySelector('[data-hook=\"avp-badge\"], .review-format-strip [class*=\"badge\"]') ? 'True' : 'False')()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "helpful_count",
            "selector": "(() => { const text = ROW.querySelector('[data-hook=\"helpful-vote-statement\"], .cr-vote-text')?.textContent?.trim() || ''; if (!text) return ''; if (/one person/i.test(text)) return '1'; const m = text.match(/[0-9,]+/); return m ? m[0].replace(/,/g, '') : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "date",
            "selector": "(() => { const text = ROW.querySelector('[data-hook=\"review-date\"], .review-date')?.textContent?.trim() || ''; const m = text.match(/on\\s+(.+)$/i); return m ? m[1].trim() : text; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "country",
            "selector": "(() => { const text = ROW.querySelector('[data-hook=\"review-date\"], .review-date')?.textContent?.trim() || ''; const m = text.match(/Reviewed\\s+in\\s+(.+?)\\s+on/i); return m ? m[1].trim() : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "vine_tag",
            "selector": "(() => Array.from(new Set(Array.from(ROW.querySelectorAll('[data-hook=\"avp-badge\"], [data-hook=\"vine-review-badge\"], .a-color-state')).map(el => el.textContent.trim()).filter(Boolean))).join('; '))()",
            "attribute": "text",
            "isJs": true
          }
        ]
      }
    },
    {
      "block_id": "sleep-2",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 6840,
      "position_y": 520,
      "config": {
        "duration": 1
      }
    },
    {
      "block_id": "loop-continue-1",
      "block_type": "process",
      "title": "Loop Continue",
      "description": "Continue multi-input loop",
      "position_x": 7176,
      "position_y": 520,
      "config": {}
    },
    {
      "block_id": "loop-continue-2",
      "block_type": "process",
      "title": "Loop Continue",
      "description": "Continue multi-input loop",
      "position_x": 6168,
      "position_y": 520,
      "config": {}
    }
  ],
  "connections": [
    {
      "from_block_id": "set-window-size-1",
      "from_connector_id": "right",
      "to_block_id": "navigate-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "navigate-2",
      "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": "sleep-3",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "sleep-3",
      "from_connector_id": "right",
      "to_block_id": "element-exists-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-2",
      "from_connector_id": "true",
      "to_block_id": "click-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-2",
      "from_connector_id": "false",
      "to_block_id": "inject-javascript-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "click-1",
      "from_connector_id": "right",
      "to_block_id": "sleep-4",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "sleep-4",
      "from_connector_id": "right",
      "to_block_id": "inject-javascript-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "inject-javascript-1",
      "from_connector_id": "right",
      "to_block_id": "sleep-5",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "sleep-5",
      "from_connector_id": "right",
      "to_block_id": "navigate-3",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "navigate-3",
      "from_connector_id": "right",
      "to_block_id": "wait-for-page-load-3",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "wait-for-page-load-3",
      "from_connector_id": "right",
      "to_block_id": "scroll-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "scroll-1",
      "from_connector_id": "right",
      "to_block_id": "sleep-6",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "sleep-6",
      "from_connector_id": "right",
      "to_block_id": "element-exists-3",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-3",
      "from_connector_id": "true",
      "to_block_id": "structured-export-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-3",
      "from_connector_id": "false",
      "to_block_id": "navigate-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "structured-export-2",
      "from_connector_id": "right",
      "to_block_id": "navigate-1",
      "to_connector_id": "left"
    },
    {
      "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": "sleep-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "sleep-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": "structured-export-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-1",
      "from_connector_id": "false",
      "to_block_id": "loop-continue-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "structured-export-1",
      "from_connector_id": "right",
      "to_block_id": "sleep-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "sleep-2",
      "from_connector_id": "right",
      "to_block_id": "loop-continue-1",
      "to_connector_id": "left"
    }
  ],
  "canvas_elements": [
    {
      "id": "group-entry",
      "element_type": "group",
      "title": "Entry & Setup",
      "color": "#4589ff",
      "position_x": 48,
      "position_y": 116,
      "width": 380,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "set-window-size-1"
        ]
      }
    },
    {
      "id": "group-load",
      "element_type": "group",
      "title": "Page Load",
      "color": "#08bdba",
      "position_x": 384,
      "position_y": 116,
      "width": 6704,
      "height": 596,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "navigate-2",
          "wait-for-page-load-2",
          "sleep-3",
          "sleep-4",
          "sleep-5",
          "navigate-3",
          "wait-for-page-load-3",
          "sleep-6",
          "navigate-1",
          "wait-for-page-load-1",
          "sleep-1",
          "sleep-2"
        ]
      }
    },
    {
      "id": "group-pagination",
      "element_type": "group",
      "title": "Pagination Loop",
      "color": "#ff832b",
      "position_x": 1392,
      "position_y": 116,
      "width": 6032,
      "height": 596,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "element-exists-2",
          "click-1",
          "element-exists-3",
          "element-exists-1",
          "loop-continue-1",
          "loop-continue-2"
        ]
      }
    },
    {
      "id": "group-interaction",
      "element_type": "group",
      "title": "Interaction",
      "color": "#a56eff",
      "position_x": 2400,
      "position_y": 416,
      "width": 1664,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "inject-javascript-1",
          "scroll-1"
        ]
      }
    },
    {
      "id": "group-extract",
      "element_type": "group",
      "title": "Data Extraction",
      "color": "#42be65",
      "position_x": 4752,
      "position_y": 416,
      "width": 2000,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "structured-export-2",
          "structured-export-1"
        ]
      }
    },
    {
      "id": "note-overview",
      "element_type": "note",
      "title": "Overview",
      "content": "Best-effort Amazon UK review scraper for ASIN B00284AO0C. Because Amazon product-reviews pages were blocked in test runs, this version first scrapes embedded review rows from the accessible product page, using robust JS fallbacks for title/content/review URL/product name, then still attempts full pagination through review pageNumber URLs 1-10 and appends all accessible rows to amazon-review-scraper-for-uk.csv. Amazon may still redirect to sign-in or CAPTCHA.",
      "color": "#f1c21b",
      "position_x": 80,
      "position_y": 20,
      "width": 480,
      "height": 160,
      "z_index": 22,
      "data": {}
    },
    {
      "id": "note-block-element-exists-2",
      "element_type": "note",
      "title": "Note: Element Exists",
      "content": "Condition block: checks `#sp-cc-accept, input[name='accept'], button[name='accept'], input#sp-cc-accept`. True / False branches control which path runs next. Keep enough space between branches so both connector lines are visible.",
      "color": "#ee5396",
      "position_x": 1664,
      "position_y": 200,
      "width": 340,
      "height": 156,
      "z_index": 22,
      "data": {
        "block_id": "element-exists-2"
      }
    },
    {
      "id": "note-block-inject-javascript-1",
      "element_type": "note",
      "title": "Note: Inject JavaScript",
      "content": "Runs custom JavaScript in the page: `(() => { const oneYear = 60 * 60 * 24 * 365; const rand = () => Math.floor(Math.random() * 9000000 +...` Verify in browser if results are empty.",
      "color": "#ee5396",
      "position_x": 2672,
      "position_y": 500,
      "width": 340,
      "height": 140,
      "z_index": 22,
      "data": {
        "block_id": "inject-javascript-1"
      }
    },
    {
      "id": "note-block-element-exists-3",
      "element_type": "note",
      "title": "Note: Element Exists",
      "content": "Condition block: checks `#cm-cr-dp-review-list div[data-hook='review'], div[data-hook='review'], div[id^='customer_review-'], [data-hook='review-`. True / False branches control which path runs next. Keep enough space between branches so both connector lines are visible.",
      "color": "#ee5396",
      "position_x": 4688,
      "position_y": 500,
      "width": 340,
      "height": 170,
      "z_index": 22,
      "data": {
        "block_id": "element-exists-3"
      }
    },
    {
      "id": "note-block-structured-export-2",
      "element_type": "note",
      "title": "Note: Structured Export",
      "content": "Structured export with JS columns (page_url, asin, brand, product_name, product_stars). These selectors are fragile — update if the site layout changes.",
      "color": "#ee5396",
      "position_x": 5024,
      "position_y": 500,
      "width": 340,
      "height": 130,
      "z_index": 22,
      "data": {
        "block_id": "structured-export-2"
      }
    },
    {
      "id": "note-block-navigate-1",
      "element_type": "note",
      "title": "Note: Navigate",
      "content": "Multi-URL loop over 10 pages. Pair with loop-continue at the end of each iteration.",
      "color": "#ee5396",
      "position_x": 5360,
      "position_y": 500,
      "width": 332,
      "height": 107,
      "z_index": 22,
      "data": {
        "block_id": "navigate-1"
      }
    },
    {
      "id": "note-block-element-exists-1",
      "element_type": "note",
      "title": "Note: Element Exists",
      "content": "Condition block: checks `div[data-hook='review'], div[id^='customer_review-'], #cm_cr-review_list .review, .review[data-hook], [data-hook='review`. True / False branches control which path runs next. Keep enough space between branches so both connector lines are visible.",
      "color": "#ee5396",
      "position_x": 6368,
      "position_y": 500,
      "width": 340,
      "height": 170,
      "z_index": 22,
      "data": {
        "block_id": "element-exists-1"
      }
    },
    {
      "id": "note-block-structured-export-1",
      "element_type": "note",
      "title": "Note: Structured Export",
      "content": "Structured export with JS columns (page_url, asin, brand, product_name, product_stars). These selectors are fragile — update if the site layout changes.",
      "color": "#ee5396",
      "position_x": 6704,
      "position_y": 500,
      "width": 340,
      "height": 130,
      "z_index": 22,
      "data": {
        "block_id": "structured-export-1"
      }
    },
    {
      "id": "note-block-loop-continue-1",
      "element_type": "note",
      "title": "Note: Loop Continue",
      "content": "Loop Continue advances a multi-URL or multi-text loop. Place at the end of the loop body with a clear back-edge to the loop start.",
      "color": "#ee5396",
      "position_x": 7376,
      "position_y": 500,
      "width": 340,
      "height": 123,
      "z_index": 22,
      "data": {
        "block_id": "loop-continue-1"
      }
    },
    {
      "id": "note-block-loop-continue-2",
      "element_type": "note",
      "title": "Note: Loop Continue",
      "content": "Loop Continue advances a multi-URL or multi-text loop. Place at the end of the loop body with a clear back-edge to the loop start.",
      "color": "#ee5396",
      "position_x": 6368,
      "position_y": 500,
      "width": 340,
      "height": 123,
      "z_index": 22,
      "data": {
        "block_id": "loop-continue-2"
      }
    }
  ]
}