{
  "version": "1.0.0",
  "exported_at": "2026-06-01T14:30:00.000Z",
  "project": {
    "name": "Naver Map Scraperby Keyword",
    "description": "Scrapes Naver Map search results by keyword for the Octoparse-equivalent fields: store name, category, open status, star rating, review count, address, nearby transport, business hours, contact number, conveniences, broadcast appearances, and search keyword. Opens Naver Map for keyword 애견호텔, redirects to Naver's generated searchIframe URL, then extracts only actual place-list title cards while filtering service-restriction/current-location/navigation text. Pagination is handled inside the collector by scrolling the result list and clicking the native Next button for up to 20 pages before one clean CSV export. If Naver returns CAPTCHA/service restriction or changes markup, rows may be empty or some fields may require selector updates.",
    "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": 260,
      "config": {
        "width": 1920,
        "height": 1080,
        "color": "bg-[#4589ff]"
      }
    },
    {
      "block_id": "navigate-1",
      "block_type": "process",
      "title": "Navigate",
      "description": "Go to a URL",
      "position_x": 480,
      "position_y": 260,
      "config": {
        "url": "https://map.naver.com/p/search/%EC%95%A0%EA%B2%AC%ED%98%B8%ED%85%94",
        "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": 840,
      "position_y": 260,
      "config": {
        "timeout": 45,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "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": "iframe#searchIframe",
        "timeout": 60,
        "visible": true,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "sleep-1",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 1560,
      "position_y": 260,
      "config": {
        "duration": 3,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "inject-javascript-1",
      "block_type": "process",
      "title": "Inject JavaScript",
      "description": "Execute custom JavaScript",
      "position_x": 1920,
      "position_y": 260,
      "config": {
        "jsCode": "(()=>{let kw='애견호텔';try{const h=decodeURIComponent(location.href);const m=h.match(/\\/search\\/([^/?#]+)/);if(m)kw=m[1];}catch(e){}const f=document.querySelector('iframe#searchIframe');let src=f&&f.getAttribute('src');if(src){if(src.startsWith('//'))src='https:'+src;else if(src.startsWith('/'))src=location.origin+src;try{const u=new URL(src);if(!u.searchParams.get('query'))u.searchParams.set('query',kw);src=u.toString();}catch(e){}location.href=src;}else{location.href='https://pcmap.place.naver.com/place/list?query='+encodeURIComponent(kw)+'&x=126.9783882&y=37.5666103';}})();",
        "waitForCompletion": true,
        "timeout": 10,
        "color": "bg-[#a56eff]"
      }
    },
    {
      "block_id": "wait-for-page-load-2",
      "block_type": "process",
      "title": "Wait for Page Load",
      "description": "Wait for page to finish loading",
      "position_x": 2280,
      "position_y": 260,
      "config": {
        "timeout": 60,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "sleep-2",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 2640,
      "position_y": 260,
      "config": {
        "duration": 5,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "inject-javascript-2",
      "block_type": "process",
      "title": "Inject JavaScript",
      "description": "Execute custom JavaScript",
      "position_x": 3000,
      "position_y": 260,
      "config": {
        "jsCode": "(async()=>{const sleep=ms=>new Promise(r=>setTimeout(r,ms));let KEYWORD='애견호텔';try{const u=new URL(location.href);KEYWORD=decodeURIComponent(u.searchParams.get('query')||u.pathname.split('/search/')[1]||KEYWORD).split('?')[0].split('/')[0];}catch(e){}const MAX_PAGES=20;const old=document.querySelector('#uscraper-naver-map-results');if(old)old.remove();const root=document.createElement('div');root.id='uscraper-naver-map-results';root.style.cssText='position:absolute;left:0;top:0;width:1px;min-height:1px;overflow:visible;background:#fff;color:#000;z-index:2147483647;font-size:1px;line-height:1px;';document.body.appendChild(root);const fields=['store_name','category','open_status','star_rating','review_count','address','nearby_transport','business_hours','contact_number','conveniences','broadcast_appearances','search_keyword'];const clean=s=>String(s==null?'':s).replace(/<[^>]*>/g,' ').replace(/&nbsp;|&#160;/g,' ').replace(/\\s+/g,' ').trim();const text=el=>clean(el&&(el.innerText||el.textContent)||'');const bad=s=>/서비스 이용이 제한|제한되었습니다|잠시 후|비정상적인 접근|captcha|CAPTCHA|로봇이 아닙니다|닫기 서비스|현재 위치에서|상세주소 열기$|출발도착$|^닫기$|^검색$|^지도$|^길찾기$|^저장$|^공유$|^전화$|^예약$|^주문$|^쿠폰$|^이전$|^다음$/.test(clean(s));const categoryWords=['반려동물호텔','애견호텔','반려동물미용','애견미용','애견카페','애견훈련','반려동물분양','동물병원','반려동물용품','펫시터','카페','음식점','식당','숙박','호텔','미용','서비스','전문점','매장','센터'];const amenities=['예약','주차','포장','배달','무선 인터넷','반려동물 동반','남/녀 화장실 구분','간편결제','단체 이용 가능','방문접수','출장','노키즈존','유아시설','장애인 편의시설','발렛파킹','지역화폐','제로페이'];const qa=(base,sel)=>{try{return Array.from(base.querySelectorAll(sel));}catch(e){return[];}};const q=(base,sel)=>{try{return base.querySelector(sel);}catch(e){return null;}};const rx=(s,r)=>{const m=String(s||'').match(r);return m?clean(m[1]||m[0]):'';};const addCell=(row,cls,val)=>{const span=document.createElement('span');span.className=cls;span.textContent=clean(val);row.appendChild(span);row.appendChild(document.createTextNode(' '));};const normalizeNameCat=(name,cat,body)=>{name=clean(name).replace(/\\s*네이버페이\\s*/g,' ').replace(/\\s*톡톡\\s*/g,' ').replace(/\\s+/g,' ').trim();cat=clean(cat);for(const w of categoryWords){if(name.endsWith(w)&&name.length>w.length+1){if(!cat)cat=w;name=clean(name.slice(0,-w.length));break;}}if(name.includes(' 네이버페이'))name=clean(name.split(' 네이버페이')[0]);if(!cat)cat=categoryWords.find(w=>body.includes(w))||'';return{name,cat};};const rowKeys=new Set();const addRow=data=>{data=Object.fromEntries(fields.map(f=>[f,clean(data[f]||'')]));const combined=Object.values(data).join(' ');if(!data.store_name||data.store_name.length<2||bad(combined)||bad(data.store_name)||!/^[가-힣A-Za-z0-9&()'’.,+\\-\\s]+$/.test(data.store_name))return;const key=clean(data.store_name+'|'+data.address+'|'+data.contact_number+'|'+data.category);if(rowKeys.has(key))return;rowKeys.add(key);const row=document.createElement('div');row.className='us-row';fields.forEach(f=>addCell(row,f,data[f]));root.appendChild(row);};const titleLinks=()=>{const raw=qa(document,'a.place_bluelink,a[class*=place_bluelink],[class*=place_bluelink] a,[class*=place_bluelink]');const links=[];raw.forEach(el=>{const a=el.tagName==='A'?el:el.closest('a')||el;const t=text(a);if(t&&t.length>=2&&t.length<=120&&!bad(t))links.push(a);});return Array.from(new Set(links));};const closestCard=el=>{let c=el;for(let i=0;i<8&&c;i++,c=c.parentElement){const t=text(c);if(t.length>40&&t.length<2200&&/(리뷰|별점|영업|전화|서울|경기|인천|부산|대구|광주|대전|울산|세종|반려동물|애견|호텔|길찾기|예약)/.test(t))return c;}return el.closest('li,[role=listitem]')||el.parentElement||el;};const parseCard=(link)=>{const card=closestCard(link);const body=text(card);let rawName=text(link).split(/[\\n\\r]+/).map(clean).filter(Boolean)[0]||text(q(card,'.place_bluelink,[class*=place_bluelink]'))||'';let cat=text(q(card,'.KCMnt,[class*=KCMnt],[class*=category],[class*=Category]'));let nc=normalizeNameCat(rawName,cat,body);let name=nc.name;cat=nc.cat;if(!name||bad(name)||/(리뷰|별점|영업|주소|전화|거리|출구|현재 위치)/.test(name))return null;let addr=rx(body,/((?:서울|부산|대구|인천|광주|대전|울산|세종|경기|강원|충북|충남|전북|전남|경북|경남|제주)[^\\n]{6,120})/);addr=clean(addr.replace(/상세주소 열기/g,'').replace(/출발도착/g,'').split(/(?:전화|리뷰|별점|방문|영업|길찾기|지도|저장|예약)/)[0]);let hours=rx(body,/((?:영업 중|영업 전|영업 종료|오늘 휴무|매일|평일|주말|24시간 영업)[^\\n]{0,90}(?:종료|시작|운영|휴무|까지)?)/);hours=clean(hours.replace(/현재 위치에서.*$/,''));return{store_name:name,category:cat,open_status:rx(body,/(영업 중|영업 전|영업 종료|오늘 휴무|휴무|곧 영업 시작|24시간 영업)/),star_rating:rx(body,/별점\\s*([0-9.]+)/)||rx(body,/\\b([1-5]\\.[0-9]{1,2})\\b/),review_count:rx(body,/방문자리뷰\\s*([0-9,]+)/)||rx(body,/방문자 리뷰\\s*([0-9,]+)/)||rx(body,/리뷰\\s*([0-9,]+)/),address:addr,nearby_transport:rx(body,/([가-힣A-Za-z0-9]+역\\s*[0-9번 ]*출구에서\\s*[^\\n ]{1,24})/),business_hours:hours,contact_number:rx(body,/(0[0-9]{1,2}-[0-9]{3,4}-[0-9]{4})/),conveniences:amenities.filter(a=>body.includes(a)).join(','),broadcast_appearances:rx(body,/((?:TV방송정보|방송출연|생방송투데이|생방송오늘저녁|생활의달인)[^\\n]{0,100})/),search_keyword:KEYWORD};};const scrollList=async()=>{const scrollers=[document.querySelector('#_pcmap_list_scroll_container'),document.querySelector('[class*=scroll]'),document.scrollingElement,document.documentElement].filter(Boolean);for(let i=0;i<8;i++){for(const s of scrollers){try{s.scrollTop=s.scrollHeight;s.dispatchEvent(new Event('scroll',{bubbles:true}));}catch(e){}}await sleep(450);}};const findNext=()=>qa(document,'a,button,[role=button]').find(b=>{const label=clean([text(b),b.getAttribute('aria-label')||'',b.getAttribute('title')||''].join(' '));const cls=String(b.className||'');const disabled=b.disabled||b.getAttribute('aria-disabled')==='true'||/disabled|inactive|Dimmed|disable/i.test(cls);return !disabled&&(label==='다음'||label.includes('다음페이지')||label.includes('다음')||label.includes('Next'));});for(let page=1;page<=MAX_PAGES;page++){await scrollList();const links=titleLinks();for(const link of links){const data=parseCard(link);if(data)addRow(data);}const next=findNext();if(!next)break;try{next.scrollIntoView({block:'center'});next.click();}catch(e){break;}await sleep(1800);}root.setAttribute('data-complete','true');root.setAttribute('data-row-count',String(root.querySelectorAll('.us-row').length));return root.getAttribute('data-row-count');})();",
        "waitForCompletion": true,
        "timeout": 240,
        "color": "bg-[#a56eff]"
      }
    },
    {
      "block_id": "wait-for-element-2",
      "block_type": "process",
      "title": "Wait for Element",
      "description": "Wait until element appears",
      "position_x": 3360,
      "position_y": 260,
      "config": {
        "selector": "#uscraper-naver-map-results[data-complete=\"true\"]",
        "timeout": 240,
        "visible": false,
        "color": "bg-[#a56eff]"
      }
    },
    {
      "block_id": "structured-export-1",
      "block_type": "process",
      "title": "Structured Export",
      "description": "Export data with custom columns",
      "position_x": 3720,
      "position_y": 260,
      "config": {
        "rowSelector": "#uscraper-naver-map-results .us-row",
        "fileName": "naver-map-scraper.csv",
        "saveLocation": "C:\\Users\\theskd\\Documents\\UScraper\\templates",
        "includeHeaders": true,
        "fileMode": "create",
        "color": "bg-[#42be65]",
        "columns": [
          {
            "name": "store_name",
            "selector": ".store_name",
            "attribute": "text"
          },
          {
            "name": "category",
            "selector": ".category",
            "attribute": "text"
          },
          {
            "name": "open_status",
            "selector": ".open_status",
            "attribute": "text"
          },
          {
            "name": "star_rating",
            "selector": ".star_rating",
            "attribute": "text"
          },
          {
            "name": "review_count",
            "selector": ".review_count",
            "attribute": "text"
          },
          {
            "name": "address",
            "selector": ".address",
            "attribute": "text"
          },
          {
            "name": "nearby_transport",
            "selector": ".nearby_transport",
            "attribute": "text"
          },
          {
            "name": "business_hours",
            "selector": ".business_hours",
            "attribute": "text"
          },
          {
            "name": "contact_number",
            "selector": ".contact_number",
            "attribute": "text"
          },
          {
            "name": "conveniences",
            "selector": ".conveniences",
            "attribute": "text"
          },
          {
            "name": "broadcast_appearances",
            "selector": ".broadcast_appearances",
            "attribute": "text"
          },
          {
            "name": "search_keyword",
            "selector": ".search_keyword",
            "attribute": "text"
          }
        ]
      }
    },
    {
      "block_id": "end-1",
      "block_type": "output",
      "title": "End",
      "description": "Terminate execution flow",
      "position_x": 4080,
      "position_y": 260,
      "config": {
        "color": "bg-[#8d8d8d]"
      }
    }
  ],
  "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": "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": "inject-javascript-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "inject-javascript-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-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "sleep-2",
      "from_connector_id": "right",
      "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-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": "structured-export-1",
      "from_connector_id": "right",
      "to_block_id": "end-1",
      "to_connector_id": "left"
    }
  ],
  "canvas_elements": [
    {
      "id": "group-entry",
      "element_type": "group",
      "title": "Entry & Setup",
      "color": "#4589ff",
      "position_x": 48,
      "position_y": 156,
      "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": 408,
      "position_y": 156,
      "width": 3200,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "navigate-1",
          "wait-for-page-load-1",
          "wait-for-element-1",
          "sleep-1",
          "wait-for-page-load-2",
          "sleep-2",
          "wait-for-element-2"
        ]
      }
    },
    {
      "id": "group-interaction",
      "element_type": "group",
      "title": "Interaction",
      "color": "#a56eff",
      "position_x": 1848,
      "position_y": 156,
      "width": 1400,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "inject-javascript-1",
          "inject-javascript-2"
        ]
      }
    },
    {
      "id": "group-extract",
      "element_type": "group",
      "title": "Data Extraction",
      "color": "#42be65",
      "position_x": 3648,
      "position_y": 156,
      "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": 4008,
      "position_y": 156,
      "width": 380,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "end-1"
        ]
      }
    },
    {
      "id": "note-overview",
      "element_type": "note",
      "title": "Overview",
      "content": "Scrapes Naver Map search results by keyword for the Octoparse-equivalent fields: store name, category, open status, star rating, review count, address, nearby transport, business hours, contact number, conveniences, broadcast appearances, and search keyword. Opens Naver Map for keyword 애견호텔, redirects to Naver's generated searchIframe URL, then extracts only actual place-list title cards while filtering service-restriction/current-location/navigation text. Pagination is handled inside the collector by scrolling the result list and clicking the native Next button for up to 20 pages before one clean CSV export. If Naver returns CAPTCHA/service restriction or changes markup, rows may be empty or some fields may require selector updates.",
      "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: `(()=>{let kw='애견호텔';try{const h=decodeURIComponent(location.href);const m=h.match(/\\/search\\/([^/?#]...` Verify in browser if results are empty.",
      "color": "#ee5396",
      "position_x": 2120,
      "position_y": 240,
      "width": 340,
      "height": 140,
      "z_index": 22,
      "data": {
        "block_id": "inject-javascript-1"
      }
    },
    {
      "id": "note-block-inject-javascript-2",
      "element_type": "note",
      "title": "Note: Inject JavaScript",
      "content": "Runs custom JavaScript in the page: `(async()=>{const sleep=ms=>new Promise(r=>setTimeout(r,ms));let KEYWORD='애견호텔';try{const u=new URL(l...` Verify in browser if results are empty.",
      "color": "#ee5396",
      "position_x": 3200,
      "position_y": 240,
      "width": 340,
      "height": 140,
      "z_index": 22,
      "data": {
        "block_id": "inject-javascript-2"
      }
    },
    {
      "id": "note-block-structured-export-1",
      "element_type": "note",
      "title": "Note: Structured Export",
      "content": "Extracts rows matching `#uscraper-naver-map-results .us-row`. Confirm row count > 0 before running at scale.",
      "color": "#ee5396",
      "position_x": 3920,
      "position_y": 240,
      "width": 340,
      "height": 116,
      "z_index": 22,
      "data": {
        "block_id": "structured-export-1"
      }
    }
  ]
}