{
  "version": "1.0.0",
  "exported_at": "2026-06-02T01:45:00.000Z",
  "project": {
    "name": "Immowelt Immobilien Listing Scraper",
    "description": "Scrapes Immowelt.de real-estate data from listing/search URLs, including title, location, price, price per m², financing text, rooms, area, agency, new-build marker, energy performance class, and item URL. The workflow loops through multiple provided listing URLs and uses a guarded next-page pagination loop to collect all available result pages. Pagination controls are filtered to avoid carousel next-slide buttons. Includes overlay cleanup for Usercentrics/DataDome-style blockers. Price parsing has been refined so main price and €/m² are separated correctly.",
    "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.immowelt.de/suche/hamburg/wohnungen/kaufen?sort=relevanz",
          "https://www.immowelt.de/suche/muenchen/haeuser/kaufen",
          "https://www.immowelt.de/suche/essen/wg/mieten?d=true&r=50&sd=DESC&sf=RELEVANCE&sp=1"
        ],
        "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": 220,
      "config": {
        "timeout": 45,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "sleep-1",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 840,
      "position_y": 220,
      "config": {
        "duration": 3,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "inject-javascript-1",
      "block_type": "process",
      "title": "Inject JavaScript",
      "description": "Run custom JavaScript on page",
      "position_x": 1200,
      "position_y": 220,
      "config": {
        "waitForCompletion": true,
        "timeout": 15,
        "color": "bg-[#a56eff]",
        "jsCode": "(function(){const norm=s=>(s||'').replace(/\\s+/g,' ').trim();const txt=el=>norm(el&&((el.innerText||el.textContent)||''));const visible=el=>!!(el&&el.offsetParent!==null);function cleanup(){try{const buttons=Array.from(document.querySelectorAll('button,a')).filter(visible);const accept=buttons.find(b=>/^(accept|accept all|akzeptieren|alle akzeptieren|zustimmen|einverstanden|auswahl speichern)$/i.test(norm(b.textContent)));if(accept)accept.click();}catch(e){}try{document.querySelectorAll('#usercentrics-root,[id*=\"usercentrics\"],[class*=\"usercentrics\"],[data-testid*=\"uc-\"],iframe[src*=\"usercentrics\"]').forEach(el=>{el.style.pointerEvents='none';el.style.display='none';});document.documentElement.style.overflow='auto';document.body.style.overflow='auto';}catch(e){}}cleanup();function lines(el){return ((el.innerText||el.textContent||'').split(/\\n+/).map(norm).filter(Boolean));}function joined(ls){return ls.join(' | ');}function first(ls,re,notRe){const v=ls.find(l=>re.test(l)&&(!notRe||!notRe.test(l)));return v||'';}function pricePerM2Text(s){let m=s.match(/\\d{1,3}(?:\\.\\d{3})*(?:,\\d+)?\\s*€\\s*\\/\\s*m²/i);return m?norm(m[0]):'';}function euroCandidates(s){return Array.from((s||'').matchAll(/\\d{1,3}(?:\\.\\d{3})+(?:,\\d+)?\\s*€|\\d{4,}(?:,\\d+)?\\s*€/g)).map(m=>({v:norm(m[0]),i:m.index||0}));}function numericEuro(v){return parseInt((v||'').replace(/[^0-9]/g,''),10)||0;}function mainPrice(titleText,ls){const sources=[titleText,joined(ls)];for(const source of sources){const cs=euroCandidates(source);for(const c of cs){const n=numericEuro(c.v);const after=source.slice(c.i+c.v.length,c.i+c.v.length+40);const before=source.slice(Math.max(0,c.i-25),c.i);if(n>=10000&&!/^\\s*\\//.test(after)&&!/\\/\\s*m²/i.test(after)&&!/Monat|finanzieren/i.test(before+' '+after)){return c.v;}}}const line=ls.find(l=>/\\d[\\d.]*,?\\d*\\s*€/.test(l)&&!/\\/\\s*m²|Monat|finanzieren/i.test(l));if(line){const m=line.match(/\\d{1,3}(?:\\.\\d{3})+(?:,\\d+)?\\s*€|\\d{4,}(?:,\\d+)?\\s*€/);return m?norm(m[0]):'';}return '';}function finance(ls){return first(ls,/(finanzieren|Ab\\s+\\d[\\d.]*,?\\d*\\s*€\\s*\\/\\s*Monat)/i);}function rooms(ls){let l=first(ls,/\\d+(?:,\\d+)?\\s*(Zimmer|Zi\\.?)/i);let m=l.match(/\\d+(?:,\\d+)?/);return m?m[0]:'';}function area(ls,titleText){const source=titleText+' | '+joined(ls);const matches=Array.from(source.matchAll(/\\d+(?:,\\d+)?\\s*m²/gi)).map(m=>({v:norm(m[0]),i:m.index||0}));for(const m of matches){const before=source.slice(Math.max(0,m.i-20),m.i);if(!/€\\s*\\/?\\s*$/i.test(before)&&!/€\\s*\\/\\s*$/i.test(before))return m.v;}return matches[0]?matches[0].v:'';}function location(ls){return first(ls,/\\b\\d{5}\\b|\\(\\d{5}\\)/);}function agency(ls){return ls.find(l=>/(^Firma\\b|^Herr\\b|^Frau\\b|GmbH|Immobilien|Makler|\\bAG\\b|\\bOHG\\b|\\bKG\\b|\\bGbR\\b)/i.test(l)&&!/(Geschoss|Zimmer|€|m²|finanzieren|Energie)/i.test(l))||'';}function energy(ls){let e=first(ls,/(Energie|Energy).*(A\\+|A|B|C|D|E|F|G|H)/i);let m=e.match(/(A\\+|A|B|C|D|E|F|G|H)\\b/);if(m)return m[1];let solo=ls.find(l=>/^(A\\+|A|B|C|D|E|F|G|H)$/.test(l));return solo||'';}function title(card,link,ls){let h=card.querySelector('h1,h2,h3,[data-testid*=title],[class*=title]');return txt(h)||norm(link&&link.getAttribute('aria-label'))||norm(link&&link.getAttribute('title'))||first(ls,/(Wohnung|Haus|Grundstück|Immobilie|Apartment|Penthouse|Neubau|Kauf|Miete)/i)||ls[0]||'';}function mark(card,link){const ls=lines(card);const titleText=title(card,link,ls);const full=titleText+' | '+joined(ls);card.setAttribute('data-uscraper-row','immowelt-property');card.setAttribute('data-us-title',titleText);card.setAttribute('data-us-standort',location(ls));card.setAttribute('data-us-preis',mainPrice(titleText,ls));card.setAttribute('data-us-preis-m2',pricePerM2Text(full));card.setAttribute('data-us-finanzieren',finance(ls));card.setAttribute('data-us-zimmer',rooms(ls));card.setAttribute('data-us-flaeche',area(ls,titleText));card.setAttribute('data-us-agency',agency(ls));card.setAttribute('data-us-ob-neu',/Neubau|Erstbezug/i.test(full)?'√':'');card.setAttribute('data-us-energy-performance-class',energy(ls));card.setAttribute('data-us-item-url',(link&&link.href)||location.href);}let candidates=[];document.querySelectorAll('a[href*=\"/expose/\"],a[href*=\"/projekte/expose/\"]').forEach(a=>{let c=a.closest('article,li,section,[data-testid*=\"card\"],[data-testid*=\"item\"],[class*=\"card\"],[class*=\"item\"]');let p=a.parentElement;let steps=0;while((!c||txt(c).length<80)&&p&&p!==document.body&&steps++<5){c=p;p=p.parentElement;}if(c)candidates.push([c,a]);});document.querySelectorAll('tr,[data-testid*=\"unit\"],[data-testid*=\"apartment\"],[class*=\"unit\"],[class*=\"apartment\"]').forEach(el=>{const t=txt(el);if(/€/.test(t)&&/m²/.test(t)&&/(Zimmer|Zi\\.?|\\d+,\\d+|\\d\\s)/i.test(t)){candidates.push([el,document.querySelector('a[href*=\"/expose/\"],a[href*=\"/projekte/expose/\"]')]);}});const seen=new Set();candidates.forEach(pair=>{const c=pair[0];if(c&&!seen.has(c)){seen.add(c);mark(c,pair[1]);}});return seen.size;})();"
      }
    },
    {
      "block_id": "wait-for-element-1",
      "block_type": "process",
      "title": "Wait for Element",
      "description": "Wait until element appears",
      "position_x": 1560,
      "position_y": 220,
      "config": {
        "selector": "[data-uscraper-row=\"immowelt-property\"]",
        "timeout": 25,
        "visible": true,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "structured-export-1",
      "block_type": "process",
      "title": "Structured Export",
      "description": "Export data with custom columns",
      "position_x": 1920,
      "position_y": 220,
      "config": {
        "rowSelector": "[data-uscraper-row=\"immowelt-property\"]",
        "fileName": "immowelt-immobilien-listing-scraper.csv",
        "saveLocation": "C:\\Users\\theskd\\Documents\\UScraper\\templates",
        "includeHeaders": true,
        "fileMode": "append",
        "color": "bg-[#42be65]",
        "columns": [
          {
            "name": "title",
            "selector": "",
            "attribute": "data-us-title"
          },
          {
            "name": "standort",
            "selector": "",
            "attribute": "data-us-standort"
          },
          {
            "name": "preis",
            "selector": "",
            "attribute": "data-us-preis"
          },
          {
            "name": "preis_m2",
            "selector": "",
            "attribute": "data-us-preis-m2"
          },
          {
            "name": "finanzieren",
            "selector": "",
            "attribute": "data-us-finanzieren"
          },
          {
            "name": "zimmer",
            "selector": "",
            "attribute": "data-us-zimmer"
          },
          {
            "name": "flaeche",
            "selector": "",
            "attribute": "data-us-flaeche"
          },
          {
            "name": "agency",
            "selector": "",
            "attribute": "data-us-agency"
          },
          {
            "name": "ob_neu",
            "selector": "",
            "attribute": "data-us-ob-neu"
          },
          {
            "name": "energy_performance_class",
            "selector": "",
            "attribute": "data-us-energy-performance-class"
          },
          {
            "name": "item_url",
            "selector": "",
            "attribute": "data-us-item-url"
          }
        ]
      }
    },
    {
      "block_id": "element-exists-1",
      "block_type": "process",
      "title": "Element Exists",
      "description": "Check if element exists",
      "position_x": 2280,
      "position_y": 220,
      "config": {
        "selector": "a[rel=\"next\"], a[aria-label*=\"nächste Seite\"]:not([aria-disabled=\"true\"]), button[aria-label*=\"nächste Seite\"]:not([disabled]), a[aria-label*=\"Weiter\"]:not([aria-label*=\"Folie\"]):not([aria-disabled=\"true\"]), button[aria-label*=\"Weiter\"]:not([aria-label*=\"Folie\"]):not([disabled]), nav a[aria-label*=\"nächste\"]:not([aria-label*=\"Folie\"]):not([aria-disabled=\"true\"]), nav button[aria-label*=\"nächste\"]:not([aria-label*=\"Folie\"]):not([disabled])",
        "color": "bg-[#ff832b]"
      }
    },
    {
      "block_id": "loop-continue-1",
      "block_type": "process",
      "title": "Loop Continue",
      "description": "Continue multi-input loop",
      "position_x": 2280,
      "position_y": 560,
      "config": {
        "color": "bg-[#8d8d8d]"
      }
    },
    {
      "block_id": "inject-javascript-2",
      "block_type": "process",
      "title": "Inject JavaScript",
      "description": "Run custom JavaScript on page",
      "position_x": 2640,
      "position_y": 560,
      "config": {
        "waitForCompletion": true,
        "timeout": 15,
        "color": "bg-[#ff832b]",
        "jsCode": "(function(){const norm=s=>(s||'').replace(/\\s+/g,' ').trim();function cleanup(){try{document.querySelectorAll('#usercentrics-root,[id*=\"usercentrics\"],[class*=\"usercentrics\"],[data-testid*=\"uc-\"],iframe[src*=\"usercentrics\"]').forEach(el=>{el.style.pointerEvents='none';el.style.display='none';});document.documentElement.style.overflow='auto';document.body.style.overflow='auto';}catch(e){}}cleanup();const visible=el=>!!(el&&el.offsetParent!==null);const sels=['a[rel=\"next\"]','a[aria-label*=\"nächste Seite\"]','button[aria-label*=\"nächste Seite\"]','a[aria-label*=\"Weiter\"]','button[aria-label*=\"Weiter\"]','nav a[aria-label*=\"nächste\"]','nav button[aria-label*=\"nächste\"]'];const candidates=Array.from(document.querySelectorAll(sels.join(','))).filter(el=>{const label=norm(el.getAttribute('aria-label')||el.textContent);const disabled=el.disabled||el.getAttribute('aria-disabled')==='true'||el.closest('[aria-disabled=\"true\"]');return visible(el)&&!disabled&&!/Folie|Slide|Carousel/i.test(label)&&/(next|weiter|nächste|seite)/i.test(label);});const el=candidates[0];if(!el)return false;el.scrollIntoView({block:'center',inline:'center'});if(el.tagName==='A'&&el.href){location.href=el.href;}else{el.click();}return true;})();"
      }
    },
    {
      "block_id": "wait-for-page-load-2",
      "block_type": "process",
      "title": "Wait for Page Load",
      "description": "Wait for page to finish loading",
      "position_x": 3000,
      "position_y": 560,
      "config": {
        "timeout": 45,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "sleep-2",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 3360,
      "position_y": 560,
      "config": {
        "duration": 3,
        "color": "bg-[#08bdba]"
      }
    }
  ],
  "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": "sleep-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "sleep-1",
      "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": "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": "false",
      "to_block_id": "loop-continue-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-1",
      "from_connector_id": "true",
      "to_block_id": "inject-javascript-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "inject-javascript-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": "inject-javascript-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": 3560,
      "height": 636,
      "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-interaction",
      "element_type": "group",
      "title": "Interaction",
      "color": "#a56eff",
      "position_x": 1128,
      "position_y": 116,
      "width": 1760,
      "height": 636,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "inject-javascript-1",
          "inject-javascript-2"
        ]
      }
    },
    {
      "id": "group-extract",
      "element_type": "group",
      "title": "Data Extraction",
      "color": "#42be65",
      "position_x": 1848,
      "position_y": 116,
      "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": 2208,
      "position_y": 116,
      "width": 380,
      "height": 636,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "element-exists-1",
          "loop-continue-1"
        ]
      }
    },
    {
      "id": "note-overview",
      "element_type": "note",
      "title": "Overview",
      "content": "Scrapes Immowelt.de real-estate data from listing/search URLs, including title, location, price, price per m², financing text, rooms, area, agency, new-build marker, energy performance class, and item URL. The workflow loops through multiple provided listing URLs and uses a guarded next-page pagination loop to collect all available result pages. Pagination controls are filtered to avoid carousel next-slide buttons. Includes overlay cleanup for Usercentrics/DataDome-style blockers. Price parsing has been refined so main price and €/m² are separated correctly.",
      "color": "#f1c21b",
      "position_x": 80,
      "position_y": 20,
      "width": 480,
      "height": 160,
      "z_index": 22,
      "data": {}
    },
    {
      "id": "note-block-inject-javascript-1",
      "element_type": "note",
      "title": "Note: Inject JavaScript",
      "content": "Runs custom JavaScript in the page: `(function(){const norm=s=>(s||'').replace(/\\s+/g,' ').trim();const txt=el=>norm(el&&((el.innerText||...` Verify in browser if results are empty.",
      "color": "#ee5396",
      "position_x": 1400,
      "position_y": 200,
      "width": 340,
      "height": 140,
      "z_index": 22,
      "data": {
        "block_id": "inject-javascript-1"
      }
    },
    {
      "id": "note-block-element-exists-1",
      "element_type": "note",
      "title": "Note: Element Exists",
      "content": "Condition block: checks `a[rel=\"next\"], a[aria-label*=\"nächste Seite\"]:not([aria-disabled=\"true\"]), button[aria-label*=\"nächste Seite\"]:not([disa`. True / False branches control which path runs next. Keep enough space between branches so both connector lines are visible.",
      "color": "#ee5396",
      "position_x": 2480,
      "position_y": 200,
      "width": 340,
      "height": 170,
      "z_index": 22,
      "data": {
        "block_id": "element-exists-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": 2480,
      "position_y": 540,
      "width": 340,
      "height": 123,
      "z_index": 22,
      "data": {
        "block_id": "loop-continue-1"
      }
    },
    {
      "id": "note-block-inject-javascript-2",
      "element_type": "note",
      "title": "Note: Inject JavaScript",
      "content": "Runs custom JavaScript in the page: `(function(){const norm=s=>(s||'').replace(/\\s+/g,' ').trim();function cleanup(){try{document.querySe...` Verify in browser if results are empty.",
      "color": "#ee5396",
      "position_x": 2840,
      "position_y": 540,
      "width": 340,
      "height": 140,
      "z_index": 22,
      "data": {
        "block_id": "inject-javascript-2"
      }
    }
  ]
}