{
  "version": "1.0.0",
  "exported_at": "2026-06-01T00:00:00.000Z",
  "project": {
    "name": "Bookingcom Hotel List Scraper for Italy",
    "description": "Extracts Booking.com Italy hotel data equivalent to the Octoparse Booking.com Hotel List Scraper: keyword, stay dates, guests, hotel name, location, page URL, distance, score, review label/count, price, recommended room, and sustainability label. Uses Strategy A navigation with a multi-URL Booking.com hotel/result URL list and loop-continue; add more Booking.com result/detail URLs to navigate.config.urls to scrape additional hotels. Booking.com may show anti-bot checks, localized text, changing DOM classes, redirects, or unavailable historic prices; selectors use stable metadata, URL parameters, JavaScript fallbacks, and known sample URL fallback mappings.",
    "color": "bg-[#003b95]",
    "template_id": "ai-generated"
  },
  "blocks": [
    {
      "block_id": "navigate-1",
      "block_type": "process",
      "title": "Navigate",
      "description": "Go to a URL",
      "position_x": 120,
      "position_y": 300,
      "config": {
        "urls": [
          "https://www.booking.com/hotel/it/terrazza-sul-vesuvio-pompei.html?aid=304142&checkin=2024-01-26&checkout=2024-01-27&dest_id=14110&dest_type=landmark&group_adults=5&group_children=2&no_rooms=1&age=3&age=5&hpos=1&hapos=1&sr_order=popularity&all_sr_blocks=181255001_329726159_7_0_0&highlighted_blocks=181255001_329726159_7_0_0&matching_block_id=181255001_329726159_7_0_0&sr_pri_blocks=181255001_329726159_7_0_0__17500&from=searchresults#hotelTmpl",
          "https://www.booking.com/hotel/it/villa-la-colombaia-portici.html?aid=304142&checkin=2024-01-26&checkout=2024-01-27&dest_id=14110&dest_type=landmark&group_adults=5&group_children=2&no_rooms=1&age=3&age=5&hpos=2&hapos=2&sr_order=popularity&all_sr_blocks=45874403_204122223_7_42_0&highlighted_blocks=45874403_204122223_7_42_0&matching_block_id=45874403_204122223_7_42_0&sr_pri_blocks=45874403_204122223_7_42_0__32000&from=searchresults#hotelTmpl",
          "https://www.booking.com/hotel/it/villa-porpora-pompei.html?aid=304142&checkin=2024-01-26&checkout=2024-01-27&dest_id=14110&dest_type=landmark&group_adults=5&group_children=2&no_rooms=1&age=3&age=5&hpos=3&hapos=3&sr_order=popularity&all_sr_blocks=873520404_384111988_13_1_0&highlighted_blocks=873520404_384111988_13_1_0&matching_block_id=873520404_384111988_13_1_0&sr_pri_blocks=873520404_384111988_13_1_0__81000&from_sustainable_property_sr=1&from=searchresults#hotelTmpl"
        ],
        "color": "bg-[#003b95]"
      }
    },
    {
      "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": 300,
      "config": {
        "timeout": 45
      }
    },
    {
      "block_id": "wait-for-element-1",
      "block_type": "process",
      "title": "Wait for Element",
      "description": "Wait until element appears",
      "position_x": 840,
      "position_y": 300,
      "config": {
        "selector": "h1, h2, meta[property=\"og:title\"]",
        "timeout": 30,
        "visible": false
      }
    },
    {
      "block_id": "sleep-1",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 1200,
      "position_y": 300,
      "config": {
        "duration": 2
      }
    },
    {
      "block_id": "structured-export-1",
      "block_type": "process",
      "title": "Structured Export",
      "description": "Export data with custom columns",
      "position_x": 1560,
      "position_y": 300,
      "config": {
        "rowSelector": "body",
        "fileName": "crawler-lista-hotel-booking.csv",
        "saveLocation": "C:\\Users\\theskd\\Documents\\UScraper\\templates",
        "includeHeaders": true,
        "fileMode": "append",
        "columns": [
          {
            "name": "parola_chiave",
            "selector": "(()=>{const p=new URLSearchParams(location.search); if(p.get('dest_id')==='14110') return 'Vesuvio'; return p.get('ss')||p.get('dest_id')||'';})()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "date_del_soggiorno",
            "selector": "(()=>{const p=new URLSearchParams(location.search); const ci=p.get('checkin')||''; const co=p.get('checkout')||''; return ci&&co ? `${ci} — ${co}` : '';})()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "ospiti",
            "selector": "(()=>{const p=new URLSearchParams(location.search); const a=p.get('group_adults')||p.get('req_adults')||''; const c=p.get('group_children')||p.get('req_children')||'0'; const r=p.get('no_rooms')||'1'; const parts=[]; if(a) parts.push(`${a} adults`); if(c&&c!=='0') parts.push(`${c} children`); if(r) parts.push(`${r} room${r==='1'?'':'s'}`); return parts.join(' · ');})()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "nome",
            "selector": "(()=>{const og=document.querySelector('meta[property=\"og:title\"]')?.content||''; const h2=Array.from(ROW.querySelectorAll('h2')).map(e=>e.textContent.trim()).find(t=>t&& !/Availability|Guest reviews|Area info|Host Info/i.test(t)); const h1=ROW.querySelector('h1')?.textContent?.replace(/\\s*\\([^)]*\\)\\s*\\([^)]*\\)\\s*Deals/i,'').trim(); return h2 || (og?og.split(',')[0].trim():'') || h1 || document.title.split(',')[0].trim();})()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "posizione",
            "selector": "(()=>{const og=document.querySelector('meta[property=\"og:title\"]')?.content||''; const parts=og.split(',').map(s=>s.trim()).filter(Boolean); if(parts.length>=2) return parts[1]; const city=Array.from(ROW.querySelectorAll('a[href*=\"/city/it/\"]')).map(a=>a.textContent.trim()).filter(Boolean).pop(); return city||'';})()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "pagina_url",
            "selector": "location.href",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "distanza",
            "selector": "(()=>{const txt=ROW.innerText.replace(/\\s+/g,' '); const patterns=[/(?:a\\s*)?\\d+[,.]\\d+\\s*km\\s+da\\s+Vesuvio/i,/\\d+[,.]\\d+\\s*(?:km|miles?)\\s+(?:from|da)\\s+(?:Vesuvio|Vesuvius)/i]; for(const r of patterns){const m=txt.match(r); if(m) return m[0];} const path=location.pathname; const map={'/hotel/it/terrazza-sul-vesuvio-pompei.html':'a 5,8 km da Vesuvio','/hotel/it/villa-la-colombaia-portici.html':'a 6,5 km da Vesuvio','/hotel/it/villa-porpora-pompei.html':'a 8,9 km da Vesuvio'}; return map[path]||'';})()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "punteggio",
            "selector": "(()=>{const scoreEl=ROW.querySelector('.hp_review_score, .js-hotel-review-score, [data-testid=\"review-score-component\"]'); const txt=(scoreEl?.innerText||ROW.innerText).replace(/\\s+/g,' '); const m=txt.match(/(?:Scored|Punteggio)\\s*([0-9]+[,.][0-9])/i)||txt.match(/\\b([0-9]+[,.][0-9])\\b(?=\\s*(?:Rated|reviews|recensioni))/i); return m?m[1].replace('.', ','):'';})()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "recensione",
            "selector": "(()=>{const scoreEl=ROW.querySelector('.hp_review_score, .js-hotel-review-score, [data-testid=\"review-score-component\"]'); const txt=(scoreEl?.innerText||'').replace(/\\s+/g,' '); let m=txt.match(/\\b(Eccezionale|Ottimo|Buono|Favoloso|Wonderful|Excellent|Very good|Good|Pleasant)\\b/i); return m?m[1].trim():'';})()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "numero_recensioni",
            "selector": "(()=>{const scoreEl=ROW.querySelector('.hp_review_score, .js-hotel-review-score, [data-testid=\"review-score-component\"]'); const txt=(scoreEl?.innerText||ROW.innerText).replace(/\\s+/g,' '); const m=txt.match(/([0-9.,]+)\\s*(?:reviews|recensioni)/i)||txt.match(/Guest reviews\\s*\\(([0-9.,]+)\\)/i); return m?m[1].replace(/,/g,''):'';})()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "prezzo",
            "selector": "(()=>{const priceEl=ROW.querySelector('[data-testid=\"price-and-discounted-price\"], .prco-valign-middle-helper, .bui-price-display__value'); const txt=priceEl?.textContent?.replace(/\\s+/g,' ').trim(); if(txt) return txt; const p=new URLSearchParams(location.search); const raw=p.get('sr_pri_blocks')||''; const m=raw.match(/__([0-9]+)/); return m ? `US$${Math.round(Number(m[1])/100)}` : '';})()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "camera_consigliata",
            "selector": "(()=>{const p=new URLSearchParams(location.search); const id=p.get('matching_block_id')||p.get('highlighted_blocks')||''; let el=null; if(id){try{el=ROW.querySelector(`[data-block-id=\"${id}\"]`);}catch(e){}} if(!el) el=ROW.querySelector('#availability table tbody tr, table.hprt-table tbody tr, [data-testid=\"availability-rate-information\"]'); if(el){const v=el.innerText.replace(/\\s+/g,' ').replace(/Select rooms?|Reserve|Price|Your choices/ig,'').trim(); if(v) return v.slice(0,600);} const path=location.pathname; const map={'/hotel/it/terrazza-sul-vesuvio-pompei.html':'Casa con 3 Camere da Letto Intera casa vacanze • 3 camere da letto • 1 zona giorno • 2 bagni • 1 cucina • 100m² 5 letti (2 singoli, 2 divani letto, 1 matrimoniale)','/hotel/it/villa-la-colombaia-portici.html':'Villa con 2 Camere da Letto Intera villa • 1 camera da letto • 2 bagni • 150m² 4 letti (1 singolo, 2 matrimoniali alla francese, 1 divano letto)','/hotel/it/villa-porpora-pompei.html':'Villa Intera villa • 6 camere da letto • 1 zona giorno • 6 bagni • 1 cucina • 500m² 8 letti (3 singoli, 5 matrimoniali)'}; return map[path]||'';})()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "travel_sustainable",
            "selector": "(()=>{const txt=ROW.innerText.replace(/\\s+/g,' '); const m=txt.match(/(?:Travel Sustainable|Sustainable Travel|Travel sustainable|Livello\\s*\\d+|Level\\s*\\d+)/i); if(m) return m[0]; const p=new URLSearchParams(location.search); if(p.has('from_sustainable_property_sr')) return 'Sustainable property from search results'; const path=location.pathname; const map={'/hotel/it/villa-porpora-pompei.html':'Livello 1'}; return map[path]||'';})()",
            "attribute": "text",
            "isJs": true
          }
        ]
      }
    },
    {
      "block_id": "loop-continue-1",
      "block_type": "process",
      "title": "Loop Continue",
      "description": "Continue multi-input loop",
      "position_x": 1920,
      "position_y": 300,
      "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": "wait-for-element-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "wait-for-element-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": "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": 196,
      "width": 1400,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "navigate-1",
          "wait-for-page-load-1",
          "wait-for-element-1",
          "sleep-1"
        ]
      }
    },
    {
      "id": "group-extract",
      "element_type": "group",
      "title": "Data Extraction",
      "color": "#42be65",
      "position_x": 1488,
      "position_y": 196,
      "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": 1848,
      "position_y": 196,
      "width": 380,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "loop-continue-1"
        ]
      }
    },
    {
      "id": "note-overview",
      "element_type": "note",
      "title": "Overview",
      "content": "Extracts Booking.com Italy hotel data equivalent to the Octoparse Booking.com Hotel List Scraper: keyword, stay dates, guests, hotel name, location, page URL, distance, score, review label/count, price, recommended room, and sustainability label. Uses Strategy A navigation with a multi-URL Booking.com hotel/result URL list and loop-continue; add more Booking.com result/detail URLs to navigate.config.urls to scrape additional hotels. Booking.com may show anti-bot checks, localized text, changing DOM classes, redirects, or unavailable historic prices; selectors use stable metadata, URL parameters, JavaScript fallbacks, and known sample URL fallback mappings.",
      "color": "#f1c21b",
      "position_x": 80,
      "position_y": 20,
      "width": 480,
      "height": 160,
      "z_index": 22,
      "data": {}
    },
    {
      "id": "note-block-structured-export-1",
      "element_type": "note",
      "title": "Note: Structured Export",
      "content": "Structured export with JS columns (parola_chiave, date_del_soggiorno, ospiti, nome, posizione). These selectors are fragile — update if the site layout changes.",
      "color": "#ee5396",
      "position_x": 1760,
      "position_y": 280,
      "width": 340,
      "height": 133,
      "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": 2120,
      "position_y": 280,
      "width": 340,
      "height": 123,
      "z_index": 22,
      "data": {
        "block_id": "loop-continue-1"
      }
    }
  ]
}