{
  "version": "1.0.0",
  "exported_at": "2026-06-02T15:30:00.000Z",
  "project": {
    "name": "AutoScout24 Scraper for Italy",
    "description": "Extracts AutoScout24 Italy car listing data equivalent to the Octoparse AutoScout24 template: brand/model, version, listing URL, subtitle/features, price, price label, mileage, transmission, year, fuel, power, dealer, dealer address, and image URL. Starts from the Maserati Italy listing URL from the Octoparse catalog. Because the listing has many pages, this template uses click-next pagination and appends all pages to crawler-di-autoscout24.csv. Cookie consent is handled conditionally when present. Pagination guard excludes disabled aria-disabled next buttons so the run ends cleanly on the final page. Some columns use JavaScript selectors because AutoScout24 uses generated CSS classes and dynamic card layouts.",
    "color": "bg-[#4589ff]",
    "template_id": "ai-generated"
  },
  "blocks": [
    {
      "block_id": "set-window-size-1",
      "block_type": "process",
      "title": "Set Window Size",
      "description": "Set browser window size",
      "position_x": 120,
      "position_y": 220,
      "config": {
        "width": 1920,
        "height": 1080,
        "color": "bg-[#4589ff]"
      }
    },
    {
      "block_id": "navigate-1",
      "block_type": "process",
      "title": "Navigate",
      "description": "Go to a URL",
      "position_x": 456,
      "position_y": 220,
      "config": {
        "url": "https://www.autoscout24.it/lst/maserati?atype=C&cy=I&desc=0&sort=standard&source=homepage_search-mask&ustate=N%2CU",
        "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": 792,
      "position_y": 220,
      "config": {
        "timeout": 30,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "element-exists-1",
      "block_type": "process",
      "title": "Element Exists",
      "description": "Check if element exists",
      "position_x": 1128,
      "position_y": 220,
      "config": {
        "selector": "button[class*='accept' i]",
        "color": "bg-[#a56eff]"
      }
    },
    {
      "block_id": "click-1",
      "block_type": "process",
      "title": "Click",
      "description": "Click on element",
      "position_x": 1464,
      "position_y": 520,
      "config": {
        "selector": "button[class*='accept' i]",
        "timeout": 8,
        "color": "bg-[#a56eff]"
      }
    },
    {
      "block_id": "sleep-1",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 1800,
      "position_y": 520,
      "config": {
        "duration": 1,
        "color": "bg-[#a56eff]"
      }
    },
    {
      "block_id": "wait-for-element-1",
      "block_type": "process",
      "title": "Wait for Element",
      "description": "Wait until element appears",
      "position_x": 2136,
      "position_y": 520,
      "config": {
        "selector": "article[data-testid='list-item']",
        "timeout": 30,
        "visible": true,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "structured-export-1",
      "block_type": "process",
      "title": "Structured Export",
      "description": "Export data with custom columns",
      "position_x": 2472,
      "position_y": 520,
      "config": {
        "rowSelector": "article[data-testid='list-item']",
        "fileName": "crawler-di-autoscout24.csv",
        "saveLocation": "C:\\Users\\theskd\\Documents\\UScraper\\templates",
        "includeHeaders": true,
        "fileMode": "append",
        "color": "bg-[#42be65]",
        "columns": [
          {
            "name": "Marca_e_Modello",
            "selector": "(ROW.querySelector('[class*=\"ListItemTitle_title\"]')?.textContent || (((ROW.getAttribute('data-make') || '') + ' ' + (ROW.getAttribute('data-model') || '')).trim())).trim()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Versione",
            "selector": "(ROW.querySelector('[class*=\"ListItemTitle_subtitle\"]')?.textContent || '').trim().replace(/\\s+/g, ' ')",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Pagina_URL",
            "selector": "(() => { const a = ROW.querySelector('a[href*=\"/annunci/\"]'); if (a) return new URL(a.getAttribute('href'), location.origin).href; const guid = ROW.getAttribute('data-guid') || ROW.id || ''; return guid ? location.origin + '/annunci/' + guid : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Sottotitolo",
            "selector": "(() => { const direct = ROW.querySelector('[class*=\"ListItemDescription\"], [class*=\"VehicleHighlights\"], [class*=\"Highlights\"], [data-testid*=\"description\"], [data-testid*=\"features\"]'); if (direct) return direct.textContent.trim().replace(/\\s+/g, ' '); const texts = Array.from(ROW.querySelectorAll('p, span[class*=\"Description\"], div[class*=\"Description\"], div[class*=\"Highlights\"]')).map(e => e.textContent.trim().replace(/\\s+/g, ' ')).filter(t => t.length > 20 && t.includes(',') && !/Pubblicità|Finanziamento|Assicurazione/i.test(t)); return texts[0] || ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Prezzo",
            "selector": "[data-testid='regular-price']",
            "attribute": "text"
          },
          {
            "name": "Etichetta",
            "selector": "(ROW.querySelector('[class*=\"PriceLabel\"] b, [class*=\"PriceEvaluation\"] b')?.textContent || '').trim().replace(/\\s+/g, ' ')",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Chilometraggio",
            "selector": "(() => { const pill = Array.from(ROW.querySelectorAll('[class*=\"ListItemPill_text\"]')).map(e => e.textContent.trim()).find(t => /km$/i.test(t)); if (pill) return pill; const mileage = ROW.getAttribute('data-mileage'); return mileage ? Number(mileage).toLocaleString('it-IT') + ' km' : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Tipo_di_cambio",
            "selector": "(() => { const pill = Array.from(ROW.querySelectorAll('[class*=\"ListItemPill_text\"]')).map(e => e.textContent.trim()).find(t => /Automatico|Manuale|Semiautomatico/i.test(t)); return pill || ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Anno",
            "selector": "(() => { const pill = Array.from(ROW.querySelectorAll('[class*=\"ListItemPill_text\"]')).map(e => e.textContent.trim()).find(t => /^\\d{2}\\/\\d{4}$/.test(t)); if (pill) return pill; const reg = ROW.getAttribute('data-first-registration') || ''; return reg ? reg.replace('-', '/') : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Carburante",
            "selector": "(() => { const pill = Array.from(ROW.querySelectorAll('[class*=\"ListItemPill_text\"]')).map(e => e.textContent.trim()).find(t => /Diesel|Benzina|Elettrica|Ibrida|GPL|Metano|Idrogeno/i.test(t)); if (pill) return pill; const code = (ROW.getAttribute('data-fuel-type') || '').toLowerCase(); const map = { d: 'Diesel', b: 'Benzina', e: 'Elettrica', l: 'GPL', c: 'Metano', h: 'Idrogeno' }; return map[code] || code; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Potenza",
            "selector": "(() => { const pill = Array.from(ROW.querySelectorAll('[class*=\"ListItemPill_text\"]')).map(e => e.textContent.trim()).find(t => /kW|CV/i.test(t)); return pill || ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Rivenditore",
            "selector": "(() => { const el = ROW.querySelector('[data-testid*=\"seller-name\"], [data-testid*=\"sellerinfo-company-name\"], [class*=\"SellerInfo_name\"], [class*=\"SellerInfoTitle\"], [class*=\"DealerInfo_name\"]'); if (el) return el.textContent.trim().replace(/\\s+/g, ' '); const text = ROW.innerText || ROW.textContent || ''; const lines = text.split('\\n').map(s => s.trim()).filter(Boolean); const idx = lines.findIndex(l => /^\\+\\s*Annunci/i.test(l)); if (idx > 1) return lines[idx - 2]; const addressIdx = lines.findIndex(l => /^IT-\\d{5}/.test(l)); return addressIdx > 0 ? lines[addressIdx - 1] : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Indirizzo_rivenditore",
            "selector": "(() => { const el = ROW.querySelector('[data-testid*=\"seller-address\"], [data-testid*=\"sellerinfo-address\"], [class*=\"SellerInfo_address\"], [class*=\"DealerInfo_address\"]'); if (el) return el.textContent.trim().replace(/\\s+/g, ' '); const text = ROW.innerText || ROW.textContent || ''; const lines = text.split('\\n').map(s => s.trim()).filter(Boolean); const idx = lines.findIndex(l => /^\\+\\s*Annunci/i.test(l)); if (idx > 0) return lines[idx - 1]; return lines.find(l => /^IT-\\d{5}/.test(l)) || ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Img_url",
            "selector": "img[data-testid='list-item-image']",
            "attribute": "src"
          }
        ]
      }
    },
    {
      "block_id": "element-exists-2",
      "block_type": "process",
      "title": "Element Exists",
      "description": "Check if element exists",
      "position_x": 2808,
      "position_y": 520,
      "config": {
        "selector": "button[aria-label*='pagina successiva' i]:not([aria-disabled='true']):not(:disabled), a[aria-label*='pagina successiva' i]:not([aria-disabled='true']), button[aria-label*='successiva' i]:not([aria-disabled='true']):not(:disabled), a[aria-label*='successiva' i]:not([aria-disabled='true']), button[aria-label*='Avanti' i]:not([aria-disabled='true']):not(:disabled), a[aria-label*='Avanti' i]:not([aria-disabled='true']), a[rel='next']:not([aria-disabled='true']), [data-testid*='pagination-next']:not([disabled]):not([aria-disabled='true'])",
        "color": "bg-[#ff832b]"
      }
    },
    {
      "block_id": "end-1",
      "block_type": "output",
      "title": "End",
      "description": "Terminate execution flow",
      "position_x": 2808,
      "position_y": 520,
      "config": {
        "color": "bg-[#8d8d8d]"
      }
    },
    {
      "block_id": "click-2",
      "block_type": "process",
      "title": "Click",
      "description": "Click on element",
      "position_x": 3144,
      "position_y": 520,
      "config": {
        "selector": "button[aria-label*='pagina successiva' i]:not([aria-disabled='true']):not(:disabled), a[aria-label*='pagina successiva' i]:not([aria-disabled='true']), button[aria-label*='successiva' i]:not([aria-disabled='true']):not(:disabled), a[aria-label*='successiva' i]:not([aria-disabled='true']), button[aria-label*='Avanti' i]:not([aria-disabled='true']):not(:disabled), a[aria-label*='Avanti' i]:not([aria-disabled='true']), a[rel='next']:not([aria-disabled='true']), [data-testid*='pagination-next']:not([disabled]):not([aria-disabled='true'])",
        "timeout": 10,
        "color": "bg-[#ff832b]"
      }
    },
    {
      "block_id": "wait-for-page-load-2",
      "block_type": "process",
      "title": "Wait for Page Load",
      "description": "Wait for page to finish loading",
      "position_x": 3480,
      "position_y": 520,
      "config": {
        "timeout": 30,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "sleep-2",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 3816,
      "position_y": 758,
      "config": {
        "duration": 2,
        "color": "bg-[#ff832b]"
      }
    }
  ],
  "connections": [
    {
      "from_block_id": "set-window-size-1",
      "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": "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": "wait-for-element-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "click-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": "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-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-2",
      "from_connector_id": "false",
      "to_block_id": "end-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-2",
      "from_connector_id": "true",
      "to_block_id": "click-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "click-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-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "sleep-2",
      "from_connector_id": "right",
      "to_block_id": "wait-for-element-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": 3680,
      "height": 834,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "navigate-1",
          "wait-for-page-load-1",
          "sleep-1",
          "wait-for-element-1",
          "wait-for-page-load-2",
          "sleep-2"
        ]
      }
    },
    {
      "id": "group-pagination",
      "element_type": "group",
      "title": "Pagination Loop",
      "color": "#ff832b",
      "position_x": 1056,
      "position_y": 116,
      "width": 2336,
      "height": 596,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "element-exists-1",
          "click-1",
          "element-exists-2",
          "click-2"
        ]
      }
    },
    {
      "id": "group-extract",
      "element_type": "group",
      "title": "Data Extraction",
      "color": "#42be65",
      "position_x": 2400,
      "position_y": 416,
      "width": 380,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "structured-export-1"
        ]
      }
    },
    {
      "id": "group-control",
      "element_type": "group",
      "title": "Control Flow",
      "color": "#8d8d8d",
      "position_x": 2736,
      "position_y": 416,
      "width": 380,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "end-1"
        ]
      }
    },
    {
      "id": "note-overview",
      "element_type": "note",
      "title": "Overview",
      "content": "Extracts AutoScout24 Italy car listing data equivalent to the Octoparse AutoScout24 template: brand/model, version, listing URL, subtitle/features, price, price label, mileage, transmission, year, fuel, power, dealer, dealer address, and image URL. Starts from the Maserati Italy listing URL from the Octoparse catalog. Because the listing has many pages, this template uses click-next pagination and appends all pages to crawler-di-autoscout24.csv. Cookie consent is handled conditionally when present. Pagination guard excludes disabled aria-disabled next buttons so the run ends cleanly on the final page. Some columns use JavaScript selectors because AutoScout24 uses generated CSS classes and dynamic card layouts.",
      "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 `button[class*='accept' i]`. True / False branches control which path runs next. Keep enough space between branches so both connector lines are visible.",
      "color": "#ee5396",
      "position_x": 1328,
      "position_y": 200,
      "width": 340,
      "height": 138,
      "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 (Marca_e_Modello, Versione, Pagina_URL, Sottotitolo, Etichetta). These selectors are fragile — update if the site layout changes.",
      "color": "#ee5396",
      "position_x": 2672,
      "position_y": 500,
      "width": 340,
      "height": 134,
      "z_index": 22,
      "data": {
        "block_id": "structured-export-1"
      }
    },
    {
      "id": "note-block-element-exists-2",
      "element_type": "note",
      "title": "Note: Element Exists",
      "content": "Condition block: checks `button[aria-label*='pagina successiva' i]:not([aria-disabled='true']):not(:disabled), a[aria-label*='pagina successiva' `. True / False branches control which path runs next. Keep enough space between branches so both connector lines are visible.",
      "color": "#ee5396",
      "position_x": 3008,
      "position_y": 500,
      "width": 340,
      "height": 170,
      "z_index": 22,
      "data": {
        "block_id": "element-exists-2"
      }
    },
    {
      "id": "note-block-click-2",
      "element_type": "note",
      "title": "Note: Click",
      "content": "Pagination click — add waits after this block; the page reloads asynchronously.",
      "color": "#ee5396",
      "position_x": 3344,
      "position_y": 500,
      "width": 316,
      "height": 106,
      "z_index": 22,
      "data": {
        "block_id": "click-2"
      }
    }
  ]
}