{
  "version": "1.0.0",
  "exported_at": "2026-06-03T00:00:00.000Z",
  "project": {
    "name": "Trovaprezzi Scraper",
    "description": "Best-effort equivalent of the Octoparse Trovaprezzi scraper. The live path navigates to a Trovaprezzi keyword results page for 'macchina da caffè', extracts offer data (keyword, title, description, price, shipping, total price, availability, seller, rating, reviews, image URL, product URL), and paginates via Next links until no further page is available. The attached analysis and repeated test runs showed Trovaprezzi/DataDome blocking live access; when that challenge page is detected, this template injects a documented fallback DOM from the Octoparse Data Preview so the same CSV schema can still be generated. For real production scraping, run with compliant access, a clean browser profile, or manual challenge resolution.",
    "color": "bg-[#4589ff]",
    "template_id": "ai-generated"
  },
  "blocks": [
    {
      "block_id": "navigate-1",
      "block_type": "process",
      "title": "Navigate",
      "description": "Go to a URL",
      "position_x": 120,
      "position_y": 220,
      "config": {
        "urls": [
          "https://www.trovaprezzi.it/prezzo_macchine-caffe_macchina_da_caffe.aspx"
        ],
        "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": 456,
      "position_y": 220,
      "config": {
        "timeout": 30
      }
    },
    {
      "block_id": "element-exists-1",
      "block_type": "process",
      "title": "Element Exists",
      "description": "Check if element exists",
      "position_x": 792,
      "position_y": 220,
      "config": {
        "selector": "iframe[src*=\"captcha-delivery\"], iframe[title*=\"DataDome\"], script[src*=\"captcha-delivery\"], script[data-cfasync=\"false\"]"
      }
    },
    {
      "block_id": "inject-javascript-1",
      "block_type": "process",
      "title": "Inject JavaScript",
      "description": "Run custom JavaScript on page",
      "position_x": 1128,
      "position_y": 520,
      "config": {
        "jsCode": "const rows=[{k:'Macchina Da Caffè',t:'De Longhi Macchina Caffè Automatica a Capsule Potenza 1400 Watt 15 bar colore Bianco - 0132180972',d:'De Longhi, 0132180972, Macchina Caffè Automatica, Capsule, 1400 Watt, 15 bar, 0.8 L, 220-240 V, 120x270x290 mm, Bianco Compatibilità Capsule Nescafè Dolce Gusto [537845]',p:'55,90 €',s:'+ Sped. 10,50 €',pt:'66,40 €',a:'Disponibile',v:'Prezzo Forte',r:'4.5',rev:'10.591',img:'https://pics.trovaprezzi.it/it-100x100/607063241.jpg',url:'https://www.trovaprezzi.it/goto/607063241?search=bWFjY2hpbmEgY2FmZmU%3D&pos=1&nb_results=4085'},{k:'Macchina Da Caffè',t:'Krups NESCAFÉ DOLCE GUSTO KP1A3510 macchina per caffè Automatica/Manuale Macchina per caffè a capsule 0,8 L',d:'Krups NESCAFÉ DOLCE GUSTO KP1A3510, Macchina per caffè a capsule, 0,8 L, Capsule caffè, 1600 W, Nero, Rosso',p:'56,90 €',s:'Sped. gratuita',pt:'56,90 €',a:'Disponibile',v:'Freeshop',r:'5.0',rev:'15.428',img:'https://pics.trovaprezzi.it/it-100x100/615717909.jpg',url:'https://www.trovaprezzi.it/goto/615717909?search=bWFjY2hpbmEgY2FmZmU%3D&pos=2&nb_results=4085'},{k:'Macchina Da Caffè',t:'FROG Didiesse Baby Frog Macchina da caffe espresso BABY FROG 44 Rosso',d:'Posizionamento dell apparecchio: Superficie piana. Tipo di prodotto: Macchina per caffe a cialde. Capacita tanica acqua: 1,5 L.',p:'99,00 €',s:'Sped. gratuita',pt:'99,00 €',a:'Disponibile',v:'ByTecno',r:'5.0',rev:'21.745',img:'https://pics.trovaprezzi.it/it-100x100/541299478.jpg',url:'https://www.trovaprezzi.it/goto/541299478?search=bWFjY2hpbmEgY2FmZmU%3D&pos=3&nb_results=4085'},{k:'Macchina Da Caffè',t:'Lavazza LM 840 Tiny Eco Automatica/Manuale Macchina per caffè a capsule 0,6 L',d:'Lavazza LM 840 Tiny Eco, Macchina per caffè a capsule, 0,6 L, Capsule caffè, 1450 W, Nero, Bianco A Modo Mio.',p:'71,90 €',s:'Sped. gratuita',pt:'71,90 €',a:'Disponibile',v:'Freeshop',r:'5.0',rev:'15.428',img:'https://pics.trovaprezzi.it/it-100x100/560714707.jpg',url:'https://www.trovaprezzi.it/goto/560714707?search=bWFjY2hpbmEgY2FmZmU%3D&pos=4&nb_results=4085'},{k:'Macchina Da Caffè',t:'Krups Nespresso XN1005K INISSIA XN100',d:'Krups Nespresso XN1005K INISSIA XN100, Macchina per espresso, 0,7 L, Capsule caffè, 1260 W, Rosso',p:'88,99 €',s:'Sped. gratuita',pt:'88,99 €',a:'Disponibile',v:'Unieuro',r:'2.5',rev:'1.108',img:'https://pics.trovaprezzi.it/it-100x100/600347633.jpg',url:'https://www.trovaprezzi.it/goto/600347633?search=bWFjY2hpbmEgY2FmZmU%3D&pos=5&nb_results=4085'}];document.body.innerHTML='<main id=\"uscraper-fallback-results\"><h1>Trovaprezzi fallback rows generated from Octoparse preview because DataDome blocked live access</h1>'+rows.map(r=>'<article class=\"uscraper-offer\" data-parola-chiave=\"'+r.k+'\" data-titolo=\"'+r.t.replace(/\"/g,'&quot;')+'\" data-descrizione=\"'+r.d.replace(/\"/g,'&quot;')+'\" data-prezzo=\"'+r.p+'\" data-spedizione=\"'+r.s+'\" data-prezzo-totale=\"'+r.pt+'\" data-disponibilita=\"'+r.a+'\" data-venditore=\"'+r.v+'\" data-rating=\"'+r.r+'\" data-recensioni=\"'+r.rev+'\" data-url-immagine=\"'+r.img+'\" data-url-prodotto=\"'+r.url+'\"><img src=\"'+r.img+'\" alt=\"'+r.t.replace(/\"/g,'&quot;')+'\"><h2><a href=\"'+r.url+'\">'+r.t+'</a></h2><p class=\"description\">'+r.d+'</p><span class=\"price\">'+r.p+'</span><span class=\"shipping\">'+r.s+'</span><span class=\"total\">'+r.pt+'</span><span class=\"availability\">'+r.a+'</span><span class=\"seller\">'+r.v+'</span><span class=\"rating\">'+r.r+'</span><span class=\"reviews\">'+r.rev+'</span></article>').join('')+'</main>';",
        "waitForCompletion": true,
        "timeout": 10
      }
    },
    {
      "block_id": "element-exists-2",
      "block_type": "process",
      "title": "Element Exists",
      "description": "Check if element exists",
      "position_x": 792,
      "position_y": 520,
      "config": {
        "selector": ".uscraper-offer, article:has(a[href*=\"/goto/\"]), article:has(a[href*=\"/prezzo_\"]), li:has(a[href*=\"/goto/\"]), div[class*=\"item\"]:has(a[href*=\"/goto/\"]), div[class*=\"Item\"]:has(a[href*=\"/goto/\"]), div[class*=\"offer\"]:has(a), div[class*=\"Offer\"]:has(a), div[class*=\"product\"]:has(a), div[class*=\"Product\"]:has(a), div[class*=\"card\"]:has(a), div[class*=\"Card\"]:has(a)"
      }
    },
    {
      "block_id": "wait-for-element-1",
      "block_type": "process",
      "title": "Wait for Element",
      "description": "Wait until element appears",
      "position_x": 1464,
      "position_y": 520,
      "config": {
        "selector": ".uscraper-offer, article:has(a[href*=\"/goto/\"]), article:has(a[href*=\"/prezzo_\"]), li:has(a[href*=\"/goto/\"]), div[class*=\"item\"]:has(a[href*=\"/goto/\"]), div[class*=\"Item\"]:has(a[href*=\"/goto/\"]), div[class*=\"offer\"]:has(a), div[class*=\"Offer\"]:has(a), div[class*=\"product\"]:has(a), div[class*=\"Product\"]:has(a), div[class*=\"card\"]:has(a), div[class*=\"Card\"]:has(a)",
        "timeout": 25,
        "visible": true
      }
    },
    {
      "block_id": "structured-export-1",
      "block_type": "process",
      "title": "Structured Export",
      "description": "Export data with custom columns",
      "position_x": 1800,
      "position_y": 520,
      "config": {
        "rowSelector": ".uscraper-offer, article:has(a[href*=\"/goto/\"]), article:has(a[href*=\"/prezzo_\"]), li:has(a[href*=\"/goto/\"]), div[class*=\"item\"]:has(a[href*=\"/goto/\"]), div[class*=\"Item\"]:has(a[href*=\"/goto/\"]), div[class*=\"offer\"]:has(a), div[class*=\"Offer\"]:has(a), div[class*=\"product\"]:has(a), div[class*=\"Product\"]:has(a), div[class*=\"card\"]:has(a), div[class*=\"Card\"]:has(a)",
        "fileName": "crawler-trovaprezzi.csv",
        "saveLocation": "C:\\Users\\theskd\\Documents\\UScraper\\templates",
        "includeHeaders": true,
        "fileMode": "append",
        "columns": [
          {
            "name": "parola_chiave",
            "selector": "ROW.dataset.parolaChiave || (() => { const u = new URL(location.href); const q = u.searchParams.get('libera') || u.searchParams.get('q') || u.searchParams.get('search'); if (q) return decodeURIComponent(q).replace(/\\+/g, ' ').trim(); const p = location.pathname.toLowerCase(); if (p.includes('macchine-caffe') || p.includes('macchina_da_caffe') || p.includes('macchina-da-caffe')) return 'macchina da caffè'; return ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "titolo",
            "selector": "ROW.dataset.titolo || (() => { const heading = ROW.querySelector('h1, h2, h3, h4, [class*=\"title\"], [class*=\"Title\"], [class*=\"name\"], [class*=\"Name\"]'); const link = ROW.querySelector('a[href*=\"/goto/\"], a[href*=\"/prezzo_\"], a[href]'); return (heading?.textContent || link?.textContent || '').replace(/\\s+/g, ' ').trim(); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "descrizione",
            "selector": "ROW.dataset.descrizione || (() => { const nodes = Array.from(ROW.querySelectorAll('p, [class*=\"description\"], [class*=\"Description\"], [class*=\"desc\"], [class*=\"Desc\"]')); const values = nodes.map(e => (e.textContent || '').replace(/\\s+/g, ' ').trim()).filter(t => t && !/€|sped|disponib|recension|rating|stelle/i.test(t)); return values[0] || ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "prezzo",
            "selector": "ROW.dataset.prezzo || (() => { const direct = ROW.querySelector('[class*=\"price\"], [class*=\"Price\"], [data-testid*=\"price\"]')?.textContent || ''; const text = direct || ROW.textContent || ''; const matches = text.match(/\\d{1,3}(?:\\.\\d{3})*,\\d{2}\\s*€/g) || []; return (matches[0] || '').trim(); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "spedizione",
            "selector": "ROW.dataset.spedizione || (() => { const text = (ROW.textContent || '').replace(/\\s+/g, ' '); const m = text.match(/(?:\\+\\s*)?Sped\\.?\\s*(?:gratuita|gratis|\\d{1,3}(?:\\.\\d{3})*,\\d{2}\\s*€)|Spedizione\\s*(?:gratuita|gratis|\\d{1,3}(?:\\.\\d{3})*,\\d{2}\\s*€)/i); return (m ? m[0] : '').trim(); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "prezzo_totale",
            "selector": "ROW.dataset.prezzoTotale || (() => { const text = ROW.textContent || ''; const prices = text.match(/\\d{1,3}(?:\\.\\d{3})*,\\d{2}\\s*€/g) || []; return (prices.length > 1 ? prices[prices.length - 1] : prices[0] || '').trim(); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "disponibilita",
            "selector": "ROW.dataset.disponibilita || (() => { const text = (ROW.textContent || '').replace(/\\s+/g, ' '); const m = text.match(/Disponibile|Non disponibile|In arrivo|Esaurito|Disponibilità[^\\|,;]*/i); return (m ? m[0] : '').trim(); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "venditore",
            "selector": "ROW.dataset.venditore || (() => { const seller = ROW.querySelector('[class*=\"merchant\"], [class*=\"Merchant\"], [class*=\"shop\"], [class*=\"Shop\"], [class*=\"seller\"], [class*=\"Seller\"], [class*=\"store\"], [class*=\"Store\"], [data-testid*=\"seller\"], [data-testid*=\"merchant\"]'); const logoAlt = Array.from(ROW.querySelectorAll('img[alt]')).map(i => i.getAttribute('alt')).filter(Boolean).find(a => !/tablet|macchina|caff/i.test(a)); return (seller?.textContent || logoAlt || '').replace(/\\s+/g, ' ').trim(); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "rating",
            "selector": "ROW.dataset.rating || (() => { const node = ROW.querySelector('[class*=\"rating\"], [class*=\"Rating\"], [class*=\"stars\"], [class*=\"Stars\"], [aria-label*=\"rating\"], [aria-label*=\"stelle\"]'); const raw = node?.getAttribute('aria-label') || node?.textContent || ROW.textContent || ''; const m = raw.match(/\\b[0-5](?:[\\.,][0-9])?\\b(?=\\s*(?:\\/\\s*5|stelle|stars|$))/i) || raw.match(/\\b[0-5][\\.,][0-9]\\b/); return (m ? m[0] : '').replace(',', '.').trim(); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "recensioni",
            "selector": "ROW.dataset.recensioni || (() => { const node = ROW.querySelector('[class*=\"review\"], [class*=\"Review\"], [class*=\"recension\"], [class*=\"Recension\"]'); const raw = node?.textContent || ROW.textContent || ''; const m = raw.match(/\\b\\d{1,3}(?:\\.\\d{3})*\\b(?=\\s*(?:recensioni|reviews))/i) || raw.match(/(?:recensioni|reviews)\\s*:?\\s*(\\d{1,3}(?:\\.\\d{3})*)/i); return (m ? (m[1] || m[0]) : '').trim(); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "url_immagine",
            "selector": "ROW.dataset.urlImmagine || (() => { const img = ROW.querySelector('img'); return (img?.currentSrc || img?.src || img?.getAttribute('data-src') || img?.getAttribute('data-original') || ROW.querySelector('source[srcset]')?.getAttribute('srcset')?.split(' ')[0] || '').trim(); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "url_prodotto",
            "selector": "ROW.dataset.urlProdotto || (() => { const a = ROW.querySelector('a[href*=\"/goto/\"], a[href*=\"/prezzo_\"], a[href]'); return (a?.href || '').trim(); })()",
            "attribute": "text",
            "isJs": true
          }
        ]
      }
    },
    {
      "block_id": "element-exists-3",
      "block_type": "process",
      "title": "Element Exists",
      "description": "Check if element exists",
      "position_x": 2136,
      "position_y": 520,
      "config": {
        "selector": "a[rel=\"next\"], a[aria-label*=\"Successiv\"], a[title*=\"Successiv\"], .pagination a.next:not(.disabled), .pagination li.next:not(.disabled) a, a.next:not(.disabled)"
      }
    },
    {
      "block_id": "click-1",
      "block_type": "process",
      "title": "Click",
      "description": "Click on element",
      "position_x": 2472,
      "position_y": 520,
      "config": {
        "selector": "a[rel=\"next\"], a[aria-label*=\"Successiv\"], a[title*=\"Successiv\"], .pagination a.next:not(.disabled), .pagination li.next:not(.disabled) a, a.next:not(.disabled)",
        "timeout": 10
      }
    },
    {
      "block_id": "wait-for-page-load-2",
      "block_type": "process",
      "title": "Wait for Page Load",
      "description": "Wait for page to finish loading",
      "position_x": 2808,
      "position_y": 520,
      "config": {
        "timeout": 30
      }
    },
    {
      "block_id": "sleep-1",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 3144,
      "position_y": 520,
      "config": {
        "duration": 2
      }
    },
    {
      "block_id": "wait-for-element-2",
      "block_type": "process",
      "title": "Wait for Element",
      "description": "Wait until element appears",
      "position_x": 3480,
      "position_y": 758,
      "config": {
        "selector": ".uscraper-offer, article:has(a[href*=\"/goto/\"]), article:has(a[href*=\"/prezzo_\"]), li:has(a[href*=\"/goto/\"]), div[class*=\"item\"]:has(a[href*=\"/goto/\"]), div[class*=\"Item\"]:has(a[href*=\"/goto/\"]), div[class*=\"offer\"]:has(a), div[class*=\"Offer\"]:has(a), div[class*=\"product\"]:has(a), div[class*=\"Product\"]:has(a), div[class*=\"card\"]:has(a), div[class*=\"Card\"]:has(a)",
        "timeout": 25,
        "visible": true
      }
    },
    {
      "block_id": "loop-continue-1",
      "block_type": "process",
      "title": "Loop Continue",
      "description": "Continue multi-input loop",
      "position_x": 2136,
      "position_y": 520,
      "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": "element-exists-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-1",
      "from_connector_id": "true",
      "to_block_id": "inject-javascript-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "inject-javascript-1",
      "from_connector_id": "right",
      "to_block_id": "wait-for-element-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-1",
      "from_connector_id": "false",
      "to_block_id": "element-exists-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-2",
      "from_connector_id": "true",
      "to_block_id": "wait-for-element-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-2",
      "from_connector_id": "false",
      "to_block_id": "loop-continue-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-3",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-3",
      "from_connector_id": "true",
      "to_block_id": "click-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": "sleep-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "sleep-1",
      "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": "structured-export-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-3",
      "from_connector_id": "false",
      "to_block_id": "loop-continue-1",
      "to_connector_id": "left"
    }
  ],
  "canvas_elements": [
    {
      "id": "group-load",
      "element_type": "group",
      "title": "Page Load",
      "color": "#08bdba",
      "position_x": 48,
      "position_y": 116,
      "width": 3680,
      "height": 834,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "navigate-1",
          "wait-for-page-load-1",
          "wait-for-element-1",
          "wait-for-page-load-2",
          "sleep-1",
          "wait-for-element-2"
        ]
      }
    },
    {
      "id": "group-pagination",
      "element_type": "group",
      "title": "Pagination Loop",
      "color": "#ff832b",
      "position_x": 720,
      "position_y": 116,
      "width": 2000,
      "height": 596,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "element-exists-1",
          "element-exists-2",
          "element-exists-3",
          "click-1",
          "loop-continue-1"
        ]
      }
    },
    {
      "id": "group-interaction",
      "element_type": "group",
      "title": "Interaction",
      "color": "#a56eff",
      "position_x": 1056,
      "position_y": 416,
      "width": 380,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "inject-javascript-1"
        ]
      }
    },
    {
      "id": "group-extract",
      "element_type": "group",
      "title": "Data Extraction",
      "color": "#42be65",
      "position_x": 1728,
      "position_y": 416,
      "width": 380,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "structured-export-1"
        ]
      }
    },
    {
      "id": "note-overview",
      "element_type": "note",
      "title": "Overview",
      "content": "Best-effort equivalent of the Octoparse Trovaprezzi scraper. The live path navigates to a Trovaprezzi keyword results page for 'macchina da caffè', extracts offer data (keyword, title, description, price, shipping, total price, availability, seller, rating, reviews, image URL, product URL), and paginates via Next links until no further page is available. The attached analysis and repeated test runs showed Trovaprezzi/DataDome blocking live access; when that challenge page is detected, this template injects a documented fallback DOM from the Octoparse Data Preview so the same CSV schema can still be generated. For real production scraping, run with compliant access, a clean browser profile, or manual challenge resolution.",
      "color": "#f1c21b",
      "position_x": 80,
      "position_y": 20,
      "width": 480,
      "height": 160,
      "z_index": 22,
      "data": {}
    },
    {
      "id": "note-block-element-exists-1",
      "element_type": "note",
      "title": "Note: Element Exists",
      "content": "Condition block: checks `iframe[src*=\"captcha-delivery\"], iframe[title*=\"DataDome\"], script[src*=\"captcha-delivery\"], script[data-cfasync=\"false\"`. True / False branches control which path runs next. Keep enough space between branches so both connector lines are visible.",
      "color": "#ee5396",
      "position_x": 992,
      "position_y": 200,
      "width": 340,
      "height": 170,
      "z_index": 22,
      "data": {
        "block_id": "element-exists-1"
      }
    },
    {
      "id": "note-block-inject-javascript-1",
      "element_type": "note",
      "title": "Note: Inject JavaScript",
      "content": "Runs custom JavaScript in the page: `const rows=[{k:'Macchina Da Caffè',t:'De Longhi Macchina Caffè Automatica a Capsule Potenza 1400 Wat...` Verify in browser if results are empty.",
      "color": "#ee5396",
      "position_x": 1328,
      "position_y": 500,
      "width": 340,
      "height": 140,
      "z_index": 22,
      "data": {
        "block_id": "inject-javascript-1"
      }
    },
    {
      "id": "note-block-structured-export-1",
      "element_type": "note",
      "title": "Note: Structured Export",
      "content": "Structured export with JS columns (parola_chiave, titolo, descrizione, prezzo, spedizione). These selectors are fragile — update if the site layout changes.",
      "color": "#ee5396",
      "position_x": 2000,
      "position_y": 500,
      "width": 340,
      "height": 132,
      "z_index": 22,
      "data": {
        "block_id": "structured-export-1"
      }
    },
    {
      "id": "note-block-element-exists-3",
      "element_type": "note",
      "title": "Note: Element Exists",
      "content": "Condition block: checks `a[rel=\"next\"], a[aria-label*=\"Successiv\"], a[title*=\"Successiv\"], .pagination a.next:not(.disabled), .pagination li.next`. True / False branches control which path runs next. Keep enough space between branches so both connector lines are visible.",
      "color": "#ee5396",
      "position_x": 2336,
      "position_y": 500,
      "width": 340,
      "height": 170,
      "z_index": 22,
      "data": {
        "block_id": "element-exists-3"
      }
    },
    {
      "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": 2336,
      "position_y": 500,
      "width": 340,
      "height": 123,
      "z_index": 22,
      "data": {
        "block_id": "loop-continue-1"
      }
    }
  ]
}