{
  "version": "1.0.0",
  "exported_at": "2026-06-03T12:00:00.000Z",
  "project": {
    "name": "Zillow Details Scraper",
    "description": "Best-effort Zillow property detail scraper equivalent to the Octoparse Zillow Details Scraper. It loops through multiple Zillow detail or address URLs, waits for page load, parses Zillow embedded JSON plus visible page labels, and appends one property row per URL to zillow-details-scraper.csv. Navigation strategy: multi-input URL loop using navigate.urls[] plus loop-continue. Replace the starter URLs with actual Zillow /homedetails/..._zpid/ URLs for production use. Zillow may block scraping with CAPTCHA, hidden body content, bot detection, or missing dynamic data; URL-derived address fallbacks are included.",
    "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": 260,
      "config": {
        "urls": [
          "https://www.zillow.com/homes/100-Ruffed-Grouse-Dr,-Shohola,-PA-18458_rb/",
          "https://www.zillow.com/homes/134-Highland-Trl,-Pleasant-Mount,-PA-18453_rb/",
          "https://www.zillow.com/homes/71-Kawlija-Road,-Grahamsville,-NY-12740_rb/",
          "https://www.zillow.com/homes/162-Fawn-Ln,-Albrightsville,-PA-18210_rb/",
          "https://www.zillow.com/homes/1371-Bell-Hill-Rd,-Delhi,-NY-13753_rb/"
        ],
        "color": "bg-[#4589ff]",
        "tags": [
          "zillow",
          "detail-url-loop"
        ]
      }
    },
    {
      "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": 260,
      "config": {
        "timeout": 45
      }
    },
    {
      "block_id": "sleep-1",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 840,
      "position_y": 260,
      "config": {
        "duration": 6
      }
    },
    {
      "block_id": "wait-for-element-1",
      "block_type": "process",
      "title": "Wait for Element",
      "description": "Wait until element appears",
      "position_x": 1200,
      "position_y": 260,
      "config": {
        "selector": "body",
        "timeout": 15,
        "visible": false
      }
    },
    {
      "block_id": "inject-javascript-1",
      "block_type": "process",
      "title": "Inject JavaScript",
      "description": "Execute custom JavaScript",
      "position_x": 1560,
      "position_y": 260,
      "config": {
        "waitForCompletion": true,
        "timeout": 25,
        "jsCode": "(function(){const D=document;const clean=v=>String(v==null?'':v).replace(/\\s+/g,' ').trim();const val=v=>{if(v==null)return'';if(typeof v==='string'||typeof v==='number'||typeof v==='boolean')return clean(v);if(Array.isArray(v))return clean(v.map(val).filter(Boolean).join(', '));if(typeof v==='object'){if(v.streetAddress||v.city)return clean([v.streetAddress,v.city,v.state,v.zipcode].filter(Boolean).join(', '));if(v.displayValue!=null)return val(v.displayValue);if(v.value!=null)return val(v.value);if(v.name!=null)return val(v.name);if(v.text!=null)return val(v.text);return clean(Object.values(v).map(val).filter(Boolean).slice(0,20).join(', '));}return clean(v);};const roots=[];function addRoot(x){if(x&&typeof x==='object')roots.push(x);}function tryJson(t){try{const x=JSON.parse(t);addRoot(x);return x;}catch(e){return null;}}for(const s of D.querySelectorAll('script')){let t=(s.textContent||'').trim().replace(/^<!--/,'').replace(/-->$/,'');if(!t)continue;tryJson(t);const i=t.indexOf('{');const j=t.lastIndexOf('}');if(i>=0&&j>i)tryJson(t.slice(i,j+1));}const seenCollect=new WeakSet();function collect(o,depth){if(!o||depth>8)return;if(typeof o==='string'){const t=o.trim().replace(/^<!--/,'').replace(/-->$/,'');if((t[0]==='{'||t[0]==='[')&&t.length<8000000){const p=tryJson(t);if(p)collect(p,depth+1);}return;}if(typeof o!=='object'||seenCollect.has(o))return;seenCollect.add(o);if(Array.isArray(o)){for(const x of o)collect(x,depth+1);}else{for(const k in o)collect(o[k],depth+1);}}for(const r of roots.slice())collect(r,0);function walk(fn){const seen=new WeakSet();function w(o){if(!o||typeof o!=='object'||seen.has(o))return;seen.add(o);fn(o);if(Array.isArray(o)){for(const x of o)w(x);}else{for(const k in o)w(o[k]);}}for(const r of roots)w(r);}let best=null,bscore=-1;walk(o=>{let s=0;['zpid','streetAddress','address','bedrooms','bathrooms','livingArea','homeType','yearBuilt','resoFacts','description','price'].forEach(k=>{if(o[k]!=null)s++;});if(o.resoFacts)s+=4;if(o.address&&typeof o.address==='object')s+=2;if(s>bscore){bscore=s;best=o;}});const prop=best||{};const reso=prop.resoFacts||prop.factsAndFeatures||prop.homeFacts||{};const addrObj=(prop.address&&typeof prop.address==='object')?prop.address:{};function firstKey(obj,names){if(!obj||typeof obj!=='object')return'';for(const n of names){for(const k in obj){if(k.toLowerCase()===n.toLowerCase()){const v=val(obj[k]);if(v)return v;}}}return'';}function key(names){let v=firstKey(addrObj,names)||firstKey(prop,names)||firstKey(reso,names);if(v)return v;let out='';walk(o=>{if(out)return;out=firstKey(o,names);});return out;}function lines(){return (D.body?D.body.innerText:'').split('\\n').map(clean).filter(Boolean);}function label(labels){const ls=lines();const low=labels.map(x=>String(x).toLowerCase());for(let i=0;i<ls.length;i++){const l=ls[i].toLowerCase();for(const lab of low){if(l===lab&&ls[i+1])return ls[i+1];if(l.startsWith(lab+':'))return clean(ls[i].slice(lab.length+1));}}return'';}function urlParts(){let s=decodeURIComponent(location.pathname);s=(s.split('/homedetails/')[1]||s.split('/homes/')[1]||s).split('/')[0];s=s.replace(/_zpid.*$/,'').replace(/_rb.*$/,'').replace(/-/g,' ');s=clean(s);const p=s.split(',').map(clean).filter(Boolean);return{address:p[0]||s,city:p[1]||'',county:''};}function room(names,fields){const rn=names.map(x=>String(x).toLowerCase());const fn=fields.map(x=>String(x).toLowerCase());let out='';const rooms=Array.isArray(reso.rooms)?reso.rooms:[];for(const r of rooms){const t=clean(r.roomType||r.name||r.type||r.roomName).toLowerCase();if(t&&rn.some(n=>t.includes(n))){for(const k in r){if(fn.includes(k.toLowerCase())){out=val(r[k]);if(out)return out;}}}}walk(o=>{if(out||!o||typeof o!=='object')return;const t=clean(o.roomType||o.name||o.type||o.roomName).toLowerCase();if(t&&rn.some(n=>t.includes(n))){for(const k in o){if(fn.includes(k.toLowerCase())){out=val(o[k]);if(out)break;}}}});return out;}const u=urlParts();const chips=Array.from(D.querySelectorAll('[data-testid=\"bed-bath-sqft-fact-container\"] span,[data-testid=\"home-details-chip\"],.ds-bed-bath-living-area-container span')).map(e=>clean(e.innerText||e.textContent)).filter(Boolean);const out={};out.address=key(['streetAddress'])||label(['Address'])||u.address;out.city=key(['city'])||u.city;out.county=key(['county','countyName'])||label(['County']);out.bed_count=key(['bedrooms','beds'])||label(['Bedrooms','Beds']);out.bath_count=key(['bathrooms','baths'])||label(['Bathrooms','Baths']);out.living_area_sqft=key(['livingArea','livingAreaValue','livingAreaSqft'])||label(['Total interior livable area','Living area','Square feet']);out.home_type=key(['homeType','propertyType','propertySubType'])||label(['Property type','Home type']);out.year_built=key(['yearBuilt'])||label(['Year built']);out.lot_size=key(['lotSize','lotAreaValue'])||label(['Lot size']);out.price_per_square_foot=key(['pricePerSquareFoot'])||label(['Price per square foot']);out.garage_parking_capacity=key(['garageParkingCapacity','parkingCapacity'])||label(['Garage spaces','Parking']);out.label_1=chips[0]||key(['homeStatus'])||'';out.label_2=chips[1]||key(['currency'])||'';out.label_3=chips[2]||'';out.description=key(['description'])||label(['Description']);out.days_on_zillow=key(['daysOnZillow','timeOnZillow'])||label(['Days on Zillow']);out.view_count=key(['pageViewCount','viewCount','views'])||label(['Views']);out.save_count=key(['favoriteCount','saveCount','saves'])||label(['Saves']);out.zillow_last_checked=key(['zillowLastChecked','lastChecked'])||new Date().toISOString();out.listing_updated=key(['listingUpdated','datePosted','datePostedString','datePriceChanged'])||label(['Listing updated','Updated']);out.listing_by=key(['attributionInfo','brokerName','agentName','listingProvidedBy'])||label(['Listed by','Listing by']);out.source=key(['mlsName','providerListingID','listingSource'])||label(['Source']);out.mls_id=key(['mlsId','mlsid','listingId'])||label(['MLS ID','MLS #']);out.originating_mls=key(['originatingSystemName','originatingMls','originatingMLS'])||label(['Originating MLS']);out.kitchen_level=room(['kitchen'],['level','roomLevel']);out.kitchen_dimensions=room(['kitchen'],['dimensions','roomDimensions','roomArea']);out.primary_bedroom_level=room(['primary bedroom','master bedroom'],['level','roomLevel']);out.primary_bedroom_dimensions=room(['primary bedroom','master bedroom'],['dimensions','roomDimensions','roomArea']);out.bedroom1_level=room(['bedroom 1','bedroom1'],['level','roomLevel']);out.bedroom1_dimensions=room(['bedroom 1','bedroom1'],['dimensions','roomDimensions','roomArea']);out.bedroom2_level=room(['bedroom 2','bedroom2'],['level','roomLevel']);out.bedroom2_dimensions=room(['bedroom 2','bedroom2'],['dimensions','roomDimensions','roomArea']);out.bathroom_level=room(['bathroom','bath'],['level','roomLevel']);out.bathroom_dimensions=room(['bathroom','bath'],['dimensions','roomDimensions','roomArea']);out.livingroom_level=room(['living room','livingroom'],['level','roomLevel']);out.livingroom_dimensions=room(['living room','livingroom'],['dimensions','roomDimensions','roomArea']);out.dining_room_level=room(['dining room'],['level','roomLevel']);out.dining_room_dimensions=room(['dining room'],['dimensions','roomDimensions','roomArea']);out.family_room_level=room(['family room'],['level','roomLevel']);out.family_room_dimensions=room(['family room'],['dimensions','roomDimensions','roomArea']);out.heating=key(['heating','heatingFeatures'])||label(['Heating']);out.cooling=key(['cooling','coolingFeatures'])||label(['Cooling']);out.appliances=key(['appliances','appliancesIncluded'])||label(['Appliances']);out.features=key(['features','specialFeatures','homeFeatures'])||label(['Features']);out.interior=key(['interiorFeatures','interior'])||label(['Interior']);out.lot_features=key(['lotFeatures'])||label(['Lot features']);out.property_features=key(['propertyFeatures','exteriorFeatures'])||label(['Property features','Exterior features']);out.parcel_number=key(['parcelNumber','taxParcelNumber'])||label(['Parcel number']);out.architectural_style=key(['architecturalStyle','style'])||label(['Architectural style']);out.materials=key(['constructionMaterials','materials'])||label(['Materials']);out.condition=key(['propertyCondition','condition'])||label(['Condition']);out.sewer=key(['sewer','sewerInformation'])||label(['Sewer']);out.water=key(['waterSource','water'])||label(['Water']);out.tax_assessed_value=key(['taxAssessedValue'])||label(['Tax assessed value']);out.annual_tax_amount=key(['annualTaxAmount','taxAnnualAmount'])||label(['Annual tax amount']);out.date_on_market=key(['dateOnMarket','onMarketDate'])||label(['Date on market']);out.listing_agreement=key(['listingAgreement'])||label(['Listing agreement']);out.inclusions=key(['inclusions'])||label(['Inclusions']);out.ownership=key(['ownership'])||label(['Ownership']);window.__zillowDetailsData=out;return out;})()"
      }
    },
    {
      "block_id": "structured-export-1",
      "block_type": "process",
      "title": "Structured Export",
      "description": "Export data with custom columns",
      "position_x": 1920,
      "position_y": 260,
      "config": {
        "rowSelector": "body",
        "fileName": "zillow-details-scraper.csv",
        "saveLocation": "C:\\Users\\theskd\\Documents\\UScraper\\templates",
        "includeHeaders": true,
        "fileMode": "append",
        "columns": [
          {
            "name": "address",
            "selector": "window.__zillowDetailsData?.address || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "city",
            "selector": "window.__zillowDetailsData?.city || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "county",
            "selector": "window.__zillowDetailsData?.county || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "bed_count",
            "selector": "window.__zillowDetailsData?.bed_count || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "bath_count",
            "selector": "window.__zillowDetailsData?.bath_count || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "living_area_sqft",
            "selector": "window.__zillowDetailsData?.living_area_sqft || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "home_type",
            "selector": "window.__zillowDetailsData?.home_type || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "year_built",
            "selector": "window.__zillowDetailsData?.year_built || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "lot_size",
            "selector": "window.__zillowDetailsData?.lot_size || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "price_per_square_foot",
            "selector": "window.__zillowDetailsData?.price_per_square_foot || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "garage_parking_capacity",
            "selector": "window.__zillowDetailsData?.garage_parking_capacity || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "label_1",
            "selector": "window.__zillowDetailsData?.label_1 || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "label_2",
            "selector": "window.__zillowDetailsData?.label_2 || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "label_3",
            "selector": "window.__zillowDetailsData?.label_3 || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "description",
            "selector": "window.__zillowDetailsData?.description || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "days_on_zillow",
            "selector": "window.__zillowDetailsData?.days_on_zillow || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "view_count",
            "selector": "window.__zillowDetailsData?.view_count || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "save_count",
            "selector": "window.__zillowDetailsData?.save_count || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "zillow_last_checked",
            "selector": "window.__zillowDetailsData?.zillow_last_checked || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "listing_updated",
            "selector": "window.__zillowDetailsData?.listing_updated || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "listing_by",
            "selector": "window.__zillowDetailsData?.listing_by || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "source",
            "selector": "window.__zillowDetailsData?.source || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "mls_id",
            "selector": "window.__zillowDetailsData?.mls_id || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "originating_mls",
            "selector": "window.__zillowDetailsData?.originating_mls || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "kitchen_level",
            "selector": "window.__zillowDetailsData?.kitchen_level || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "kitchen_dimensions",
            "selector": "window.__zillowDetailsData?.kitchen_dimensions || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "primary_bedroom_level",
            "selector": "window.__zillowDetailsData?.primary_bedroom_level || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "primary_bedroom_dimensions",
            "selector": "window.__zillowDetailsData?.primary_bedroom_dimensions || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "bedroom1_level",
            "selector": "window.__zillowDetailsData?.bedroom1_level || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "bedroom1_dimensions",
            "selector": "window.__zillowDetailsData?.bedroom1_dimensions || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "bedroom2_level",
            "selector": "window.__zillowDetailsData?.bedroom2_level || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "bedroom2_dimensions",
            "selector": "window.__zillowDetailsData?.bedroom2_dimensions || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "bathroom_level",
            "selector": "window.__zillowDetailsData?.bathroom_level || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "bathroom_dimensions",
            "selector": "window.__zillowDetailsData?.bathroom_dimensions || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "livingroom_level",
            "selector": "window.__zillowDetailsData?.livingroom_level || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "livingroom_dimensions",
            "selector": "window.__zillowDetailsData?.livingroom_dimensions || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "dining_room_level",
            "selector": "window.__zillowDetailsData?.dining_room_level || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "dining_room_dimensions",
            "selector": "window.__zillowDetailsData?.dining_room_dimensions || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "family_room_level",
            "selector": "window.__zillowDetailsData?.family_room_level || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "family_room_dimensions",
            "selector": "window.__zillowDetailsData?.family_room_dimensions || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "heating",
            "selector": "window.__zillowDetailsData?.heating || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "cooling",
            "selector": "window.__zillowDetailsData?.cooling || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "appliances",
            "selector": "window.__zillowDetailsData?.appliances || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "features",
            "selector": "window.__zillowDetailsData?.features || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "interior",
            "selector": "window.__zillowDetailsData?.interior || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "lot_features",
            "selector": "window.__zillowDetailsData?.lot_features || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "property_features",
            "selector": "window.__zillowDetailsData?.property_features || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "parcel_number",
            "selector": "window.__zillowDetailsData?.parcel_number || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "architectural_style",
            "selector": "window.__zillowDetailsData?.architectural_style || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "materials",
            "selector": "window.__zillowDetailsData?.materials || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "condition",
            "selector": "window.__zillowDetailsData?.condition || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "sewer",
            "selector": "window.__zillowDetailsData?.sewer || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "water",
            "selector": "window.__zillowDetailsData?.water || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "tax_assessed_value",
            "selector": "window.__zillowDetailsData?.tax_assessed_value || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "annual_tax_amount",
            "selector": "window.__zillowDetailsData?.annual_tax_amount || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "date_on_market",
            "selector": "window.__zillowDetailsData?.date_on_market || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "listing_agreement",
            "selector": "window.__zillowDetailsData?.listing_agreement || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "inclusions",
            "selector": "window.__zillowDetailsData?.inclusions || ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "ownership",
            "selector": "window.__zillowDetailsData?.ownership || ''",
            "attribute": "text",
            "isJs": true
          }
        ]
      }
    },
    {
      "block_id": "loop-continue-1",
      "block_type": "process",
      "title": "Loop Continue",
      "description": "Continue multi-input loop",
      "position_x": 2280,
      "position_y": 260,
      "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": "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": "inject-javascript-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "inject-javascript-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": "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": 156,
      "width": 1400,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "navigate-1",
          "wait-for-page-load-1",
          "sleep-1",
          "wait-for-element-1"
        ]
      }
    },
    {
      "id": "group-interaction",
      "element_type": "group",
      "title": "Interaction",
      "color": "#a56eff",
      "position_x": 1488,
      "position_y": 156,
      "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": 1848,
      "position_y": 156,
      "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": 156,
      "width": 380,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "loop-continue-1"
        ]
      }
    },
    {
      "id": "note-overview",
      "element_type": "note",
      "title": "Overview",
      "content": "Best-effort Zillow property detail scraper equivalent to the Octoparse Zillow Details Scraper. It loops through multiple Zillow detail or address URLs, waits for page load, parses Zillow embedded JSON plus visible page labels, and appends one property row per URL to zillow-details-scraper.csv. Navigation strategy: multi-input URL loop using navigate.urls[] plus loop-continue. Replace the starter URLs with actual Zillow /homedetails/..._zpid/ URLs for production use. Zillow may block scraping with CAPTCHA, hidden body content, bot detection, or missing dynamic data; URL-derived address fallbacks are included.",
      "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 D=document;const clean=v=>String(v==null?'':v).replace(/\\s+/g,' ').trim();const va...` Verify in browser if results are empty.",
      "color": "#ee5396",
      "position_x": 1760,
      "position_y": 240,
      "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 (address, city, county, bed_count, bath_count). These selectors are fragile — update if the site layout changes.",
      "color": "#ee5396",
      "position_x": 2120,
      "position_y": 240,
      "width": 340,
      "height": 128,
      "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": 2480,
      "position_y": 240,
      "width": 340,
      "height": 123,
      "z_index": 22,
      "data": {
        "block_id": "loop-continue-1"
      }
    }
  ]
}