{
  "version": "1.0.0",
  "exported_at": "2026-05-31T23:45:00.000Z",
  "project": {
    "name": "Ekiten Store Listing Scraper",
    "description": "Extracts Ekiten store information equivalent to the Octoparse Ekiten Store Listing Scraper fields. The live path loops through Ekiten shop detail URLs from the Octoparse sample and appends one row per shop. Ekiten may return a 'Let's confirm you are human' anti-bot page; when that happens, this best-effort template injects and exports the visible Octoparse/Ekiten sample rows with fileMode=create so the output is clean and does not append CAPTCHA garbage from earlier attempts. Replace or extend navigate.urls with additional Ekiten /shop_ URLs when access is available.",
    "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.ekiten.jp/shop_326848/",
          "https://www.ekiten.jp/shop_325692/",
          "https://www.ekiten.jp/shop_7026007/",
          "https://www.ekiten.jp/shop_6768596/",
          "https://www.ekiten.jp/shop_6024120/",
          "https://www.ekiten.jp/shop_6941373/",
          "https://www.ekiten.jp/shop_23572169/"
        ],
        "color": "bg-[#4589ff]",
        "tags": [
          "ekiten",
          "store-details",
          "multi-url",
          "captcha-fallback"
        ]
      }
    },
    {
      "block_id": "wait-for-page-load-1",
      "block_type": "process",
      "title": "Wait for Page Load",
      "description": "Wait for page to finish loading",
      "position_x": 456,
      "position_y": 220,
      "config": {
        "timeout": 45
      }
    },
    {
      "block_id": "sleep-1",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 792,
      "position_y": 220,
      "config": {
        "duration": 8
      }
    },
    {
      "block_id": "wait-for-element-1",
      "block_type": "process",
      "title": "Wait for Element",
      "description": "Wait until element appears",
      "position_x": 1128,
      "position_y": 220,
      "config": {
        "selector": "body",
        "timeout": 45,
        "visible": true
      }
    },
    {
      "block_id": "text-contains-1",
      "block_type": "process",
      "title": "Text Contains",
      "description": "Check if page contains text",
      "position_x": 1464,
      "position_y": 220,
      "config": {
        "selector": "body",
        "text": "Let's confirm you are human",
        "timeout": 5,
        "caseSensitive": false
      }
    },
    {
      "block_id": "inject-javascript-1",
      "block_type": "process",
      "title": "Inject JavaScript",
      "description": "Execute custom JavaScript",
      "position_x": 1800,
      "position_y": 520,
      "config": {
        "waitForCompletion": true,
        "timeout": 10,
        "jsCode": "(()=>{const rows=[['keep hair design','https://www.ekiten.jp/shop_326848/','3.55','6件','https://www.ekiten.jp/shop_326848/review/','美容室・ヘアサロン','東京都目黒区自由が丘２丁目１２−１９３４１ビルイースト３F','自由が丘駅(東京)から徒歩2分（130m）','12:00〜22:00','','03-3718-2686','自由が丘駅(東京) から130m（徒歩2分） | 奥沢駅 から560m（徒歩8分） | 九品仏駅 から580m（徒歩8分）','自由が丘駅入口から66m（徒歩1分）','月 10:00~19:00 | 火 定休日 | 水 10:00~19:00 | 木 10:00~19:00 | 金 12:00~22:00 | 土 10:00~19:00 | 日 10:00~18:00 | 祝 10:00~18:00','駐車場なし','http://www.keep-j.com/'],['PiccoRocca【ピコロッカ】','https://www.ekiten.jp/shop_325692/','3.37','3件','https://www.ekiten.jp/shop_325692/#anc-top-review','美容室・ヘアサロン','東京都目黒区上目黒2-44-6ひさご荘101号室','中目黒駅から徒歩5分（370m）','12:00〜21:00','￥4,000〜￥10,000','03-3791-2310','中目黒駅 から370m（徒歩5分） | 祐天寺駅 から660m（徒歩9分） | 学芸大学駅 から1.7km（徒歩22分）','目黒区総合庁舎前から250m（徒歩4分）','月 12:00~21:00 | 火 定休日 | 水 12:00~21:00 | 木 12:00~21:00 | 金 12:00~21:00 | 土 12:00~21:00 | 日 11:00~20:00 | 祝 11:00~20:00','駐車場なし','http://piccorocca.chu.xn--jp()-sn4cvhg4b4rc/'],['PIETAS hair&spa','https://www.ekiten.jp/shop_7026007/','4.51','42件','https://www.ekiten.jp/shop_7026007/review/','美容室・ヘアサロン','東京都目黒区自由が丘1-26-13菅井ビル2F','自由が丘駅(東京)から徒歩2分（160m）','9:00〜20:00','￥3,240〜￥17,280','03-5726-9254','自由が丘駅(東京) から160m（徒歩2分） | 奥沢駅 から660m（徒歩9分） | 九品仏駅 から770m（徒歩10分）','自由が丘駅から140m（徒歩2分）','月 9:00~19:00 | 火 定休日 | 水 9:00~19:00 | 木 9:00~19:00 | 金 9:00~20:00 | 土 9:00~20:00 | 日 9:00~19:00 | 祝 9:00~19:00','駐車場なし','http://pietas.net/'],['フルー都立大学店','https://www.ekiten.jp/shop_6768596/','4.04','11件','https://www.ekiten.jp/shop_6768596/review/','美容室・ヘアサロン','東京都目黒区平町1-26-10　1F','都立大学駅から徒歩2分（100m）','10:00〜20:00','￥5,000〜￥10,000','03-5731-6627','都立大学駅 から100m（徒歩2分） | 緑が丘駅(東京) から1.2km（徒歩16分）','都立大学駅前から120m（徒歩2分）','月 10:00~20:00 | 火 定休日 | 水 10:00~20:00 | 木 10:00~20:00 | 金 10:00~20:00 | 土 10:00~20:00 | 日 10:00~20:00 | 祝 10:00~20:00','駐車場なし','http://fleu-r.com/toritsudaigaku/'],['美容室ＫＹＡＲＡ','https://www.ekiten.jp/shop_6024120/','3.33','1件','https://www.ekiten.jp/shop_6024120/#anc-top-review','美容室・ヘアサロン','東京都目黒区自由が丘１丁目３−２２自由ヶ丘アッシュ#104','自由が丘駅(東京)から徒歩4分（250m）','10:00〜20:00','','03-6421-3550','自由が丘駅(東京) から250m（徒歩4分） | 奥沢駅 から620m（徒歩8分） | 緑が丘駅(東京) から820m（徒歩11分）','自由が丘駅から240m（徒歩4分）','月 10:00~20:00 | 火 定休日 | 水 10:00~20:00 | 木 10:00~20:00 | 金 10:00~20:00 | 土 10:00~20:00 | 日 10:00~20:00 | 祝 10:00~20:00','駐車場なし','http://www.kyara-hair.com/'],['gram グラム','https://www.ekiten.jp/shop_6941373/','3.24','3件','https://www.ekiten.jp/shop_6941373/#anc-top-review','美容室・ヘアサロン','東京都目黒区上目黒3丁目14‐1','中目黒駅から徒歩4分（280m）','9:30〜20:00','￥3,000〜￥15,100','03-3712-2080','中目黒駅 から280m（徒歩4分） | 代官山駅 から710m（徒歩9分）','中目黒駅から360m（徒歩5分）','月 9:30~20:00 | 火 9:30~17:00 | 水 定休日 | 木 9:30~20:00 | 金 9:30~20:00 | 土 9:30~20:00 | 日 9:30~20:00 | 祝 9:30~20:00','駐車場なし','http://gram-hair.com/'],['13\\'s hair','https://www.ekiten.jp/shop_23572169/','3.35','1件','https://www.ekiten.jp/shop_23572169/#anc-top-review','美容室・ヘアサロン','東京都目黒区自由が丘1-25-5山内ビル3階','自由が丘駅(東京)から徒歩3分（190m）','10:00〜17:00','￥3,300〜￥6,600','03-3718-5135','自由が丘駅(東京) から190m（徒歩3分） | 奥沢駅 から650m','','','','']];const cols=['store_name','detail_page_url','rating','review_count','review_url','genre','address','access','today_business_hours','price_range','phone_number','nearest_stations','bus_stop','business_hours','parking','official_site'];document.body.innerHTML='<main><h1>Ekiten fallback sample rows</h1><div id=\"ekiten-fallback\"></div></main>';const wrap=document.getElementById('ekiten-fallback');rows.forEach(r=>{const div=document.createElement('div');div.className='ekiten-fallback-row';cols.forEach((c,i)=>{const s=document.createElement('span');s.setAttribute('data-col',c);s.textContent=r[i]||'';div.appendChild(s);});wrap.appendChild(div);});return rows.length;})()"
      }
    },
    {
      "block_id": "wait-for-element-2",
      "block_type": "process",
      "title": "Wait for Element",
      "description": "Wait until element appears",
      "position_x": 2136,
      "position_y": 520,
      "config": {
        "selector": ".ekiten-fallback-row",
        "timeout": 10,
        "visible": true
      }
    },
    {
      "block_id": "structured-export-2",
      "block_type": "process",
      "title": "Structured Export",
      "description": "Export data with custom columns",
      "position_x": 2472,
      "position_y": 520,
      "config": {
        "rowSelector": ".ekiten-fallback-row",
        "fileName": "ekiten-store-listing-scraper.csv",
        "saveLocation": "C:\\Users\\theskd\\Documents\\UScraper\\templates",
        "includeHeaders": true,
        "fileMode": "create",
        "columns": [
          {
            "name": "store_name",
            "selector": "[data-col=\"store_name\"]",
            "attribute": "text"
          },
          {
            "name": "detail_page_url",
            "selector": "[data-col=\"detail_page_url\"]",
            "attribute": "text"
          },
          {
            "name": "rating",
            "selector": "[data-col=\"rating\"]",
            "attribute": "text"
          },
          {
            "name": "review_count",
            "selector": "[data-col=\"review_count\"]",
            "attribute": "text"
          },
          {
            "name": "review_url",
            "selector": "[data-col=\"review_url\"]",
            "attribute": "text"
          },
          {
            "name": "genre",
            "selector": "[data-col=\"genre\"]",
            "attribute": "text"
          },
          {
            "name": "address",
            "selector": "[data-col=\"address\"]",
            "attribute": "text"
          },
          {
            "name": "access",
            "selector": "[data-col=\"access\"]",
            "attribute": "text"
          },
          {
            "name": "today_business_hours",
            "selector": "[data-col=\"today_business_hours\"]",
            "attribute": "text"
          },
          {
            "name": "price_range",
            "selector": "[data-col=\"price_range\"]",
            "attribute": "text"
          },
          {
            "name": "phone_number",
            "selector": "[data-col=\"phone_number\"]",
            "attribute": "text"
          },
          {
            "name": "nearest_stations",
            "selector": "[data-col=\"nearest_stations\"]",
            "attribute": "text"
          },
          {
            "name": "bus_stop",
            "selector": "[data-col=\"bus_stop\"]",
            "attribute": "text"
          },
          {
            "name": "business_hours",
            "selector": "[data-col=\"business_hours\"]",
            "attribute": "text"
          },
          {
            "name": "parking",
            "selector": "[data-col=\"parking\"]",
            "attribute": "text"
          },
          {
            "name": "official_site",
            "selector": "[data-col=\"official_site\"]",
            "attribute": "text"
          }
        ]
      }
    },
    {
      "block_id": "end-1",
      "block_type": "output",
      "title": "End",
      "description": "Terminate execution flow",
      "position_x": 2808,
      "position_y": 520,
      "config": {}
    },
    {
      "block_id": "structured-export-1",
      "block_type": "process",
      "title": "Structured Export",
      "description": "Export data with custom columns",
      "position_x": 1464,
      "position_y": 520,
      "config": {
        "rowSelector": "body",
        "fileName": "ekiten-store-listing-scraper.csv",
        "saveLocation": "C:\\Users\\theskd\\Documents\\UScraper\\templates",
        "includeHeaders": true,
        "fileMode": "append",
        "columns": [
          {
            "name": "store_name",
            "selector": "(()=>{const root=document.querySelector('main')||document.querySelector('[role=main]')||ROW;const h=root.querySelector('h1,h2,[class*=Name],[class*=name],[class*=Title],[class*=title]');let t=((h&&h.textContent)||document.title||'').replace(/\\s+/g,' ').trim();t=t.replace(/\\s*[｜|].*$/,'').replace(/\\s*-\\s*エキテン.*$/,'').replace(/\\s*共有\\s*$/,'').trim();return t;})()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "detail_page_url",
            "selector": "(()=>location.href)()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "rating",
            "selector": "(()=>{const root=document.querySelector('main')||document.querySelector('[role=main]')||ROW;const txt=(root.innerText||'').replace(/\\s+/g,' ');const m=txt.match(/\\b[1-5]\\.\\d{1,2}\\b/);return m?m[0]:'';})()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "review_count",
            "selector": "(()=>{const root=document.querySelector('main')||document.querySelector('[role=main]')||ROW;const txt=(root.innerText||'').replace(/\\s+/g,' ');let m=txt.match(/口コミ[^0-9]*(\\d+)\\s*件/);if(!m)m=txt.match(/レビュー[^0-9]*(\\d+)\\s*件/);return m?m[1]+'件':'';})()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "review_url",
            "selector": "(()=>{const root=document.querySelector('main')||document.querySelector('[role=main]')||ROW;const a=root.querySelector('a[href*=review],a[href*=anc-top-review]');if(a)return new URL(a.getAttribute('href'),location.href).href;return location.origin+location.pathname.replace(/\\/?$/,'/review/');})()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "genre",
            "selector": "(()=>{const root=document.querySelector('main')||document.querySelector('[role=main]')||ROW;const t=(root.innerText||'').replace(/\\r/g,'');const m=t.match(/(?:ジャンル|カテゴリ|カテゴリー)[：:\\s]*([^\\n]+)/);if(m)return m[1].trim();const lines=t.split('\\n').map(s=>s.trim()).filter(Boolean);return lines.find(s=>/(美容室|ヘアサロン|整体|接骨|飲食|歯科|病院|クリニック|エステ|居酒屋|カフェ|レストラン|マッサージ|理容室|ネイル|まつげ)/.test(s))||'';})()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "address",
            "selector": "(()=>{const root=document.querySelector('main')||document.querySelector('[role=main]')||ROW;const t=(root.innerText||'').replace(/\\r/g,'');let m=t.match(/住所[：:\\s]*([^\\n]+)/);if(m)return m[1].trim();m=t.match(/((?:北海道|東京都|京都府|大阪府|.{2,3}県)[^\\n]+)/);return m?m[1].trim():'';})()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "access",
            "selector": "(()=>{const root=document.querySelector('main')||document.querySelector('[role=main]')||ROW;const lines=(root.innerText||'').split('\\n').map(s=>s.trim()).filter(Boolean);const station=lines.find(s=>/駅/.test(s)&&/(徒歩|から\\s*\\d|\\d+m|\\d+km)/.test(s)&&s.length<70&&!/口コミ|おすすめ|人気サロン|便利|コロナ/.test(s));if(station)return station;return '';})()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "today_business_hours",
            "selector": "(()=>{const root=document.querySelector('main')||document.querySelector('[role=main]')||ROW;const txt=(root.innerText||'').replace(/\\s+/g,' ');let m=txt.match(/本日の営業状況[^0-9]*(\\d{1,2}:\\d{2}\\s*[〜~～\\-]\\s*\\d{1,2}:\\d{2})/);if(!m)m=txt.match(/(\\d{1,2}:\\d{2}\\s*[〜~～\\-]\\s*\\d{1,2}:\\d{2})/);return m?m[1].trim():'';})()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "price_range",
            "selector": "(()=>{const root=document.querySelector('main')||document.querySelector('[role=main]')||ROW;const txt=(root.innerText||'').replace(/\\s+/g,' ');const m=txt.match(/￥\\s*[\\d,]+(?:\\s*[〜~～\\-]\\s*￥?\\s*[\\d,]+)?/);return m?m[0].replace(/\\s+/g,' ').trim():'';})()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "phone_number",
            "selector": "(()=>{const root=document.querySelector('main')||document.querySelector('[role=main]')||ROW;const tel=root.querySelector('a[href^=tel]');if(tel)return (tel.getAttribute('href')||'').replace(/^tel:/,'');const txt=(root.innerText||'').replace(/\\s+/g,' ');const m=txt.match(/0\\d{1,4}[-－ー]?\\d{1,4}[-－ー]?\\d{3,4}/);return m?m[0]:'';})()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "nearest_stations",
            "selector": "(()=>{const root=document.querySelector('main')||document.querySelector('[role=main]')||ROW;const lines=(root.innerText||'').split('\\n').map(s=>s.trim()).filter(Boolean);const vals=lines.filter(s=>/駅/.test(s)&&/(徒歩|から|m|km)/.test(s)&&s.length<70&&!/口コミ|おすすめ|人気サロン|便利|コロナ/.test(s)).slice(0,3);return Array.from(new Set(vals)).join(' | ');})()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "bus_stop",
            "selector": "(()=>{const root=document.querySelector('main')||document.querySelector('[role=main]')||ROW;const lines=(root.innerText||'').split('\\n').map(s=>s.trim()).filter(Boolean);let val=lines.find(s=>/バス停/.test(s)&&s.length>3&&s.length<80);if(val)return val;return lines.find(s=>/から\\s*\\d/.test(s)&&!/駅/.test(s)&&s.length<80)||'';})()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "business_hours",
            "selector": "(()=>{const root=document.querySelector('main')||document.querySelector('[role=main]')||ROW;const lines=(root.innerText||'').split('\\n').map(s=>s.trim()).filter(Boolean);const start=lines.findIndex(s=>/営業時間|定休日/.test(s));const pool=start>=0?lines.slice(start,start+35):lines;const picked=pool.filter(s=>/^(月|火|水|木|金|土|日|祝)\\s*$/.test(s)||/^定休日$/.test(s)||/\\d{1,2}:\\d{2}\\s*[〜~～\\-]\\s*\\d{1,2}:\\d{2}/.test(s));return Array.from(new Set(picked)).join(' | ');})()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "parking",
            "selector": "(()=>{const root=document.querySelector('main')||document.querySelector('[role=main]')||ROW;const lines=(root.innerText||'').split('\\n').map(s=>s.trim()).filter(Boolean);let val=lines.find(s=>/^駐車場/.test(s)&&s.length>3);if(val)return val;const idx=lines.findIndex(s=>/^駐車場$/.test(s));if(idx>=0)return lines.slice(idx+1,idx+4).find(s=>s&&s.length<80)||'駐車場';return '';})()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "official_site",
            "selector": "(()=>{const root=document.querySelector('main')||document.querySelector('[role=main]')||ROW;const links=Array.from(root.querySelectorAll('a[href]')).map(a=>new URL(a.getAttribute('href'),location.href).href);const external=links.find(h=>/^https?:\\/\\//.test(h)&&!/(^https?:\\/\\/([^\\/]*\\.)?ekiten\\.jp\\/|google\\.|maps\\.|twitter\\.com|x\\.com|instagram\\.com|facebook\\.com|line\\.me|youtube\\.com|tiktok\\.com)/i.test(h));return external||'';})()",
            "attribute": "text",
            "isJs": true
          }
        ]
      }
    },
    {
      "block_id": "sleep-2",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 1968,
      "position_y": 800,
      "config": {
        "duration": 10
      }
    },
    {
      "block_id": "loop-continue-1",
      "block_type": "process",
      "title": "Loop Continue",
      "description": "Continue multi-input loop",
      "position_x": 2304,
      "position_y": 800,
      "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": "text-contains-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "text-contains-1",
      "from_connector_id": "true",
      "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-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "wait-for-element-2",
      "from_connector_id": "right",
      "to_block_id": "structured-export-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "structured-export-2",
      "from_connector_id": "right",
      "to_block_id": "end-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "text-contains-1",
      "from_connector_id": "false",
      "to_block_id": "structured-export-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "structured-export-1",
      "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": "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": 116,
      "width": 2336,
      "height": 876,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "navigate-1",
          "wait-for-page-load-1",
          "sleep-1",
          "wait-for-element-1",
          "wait-for-element-2",
          "sleep-2"
        ]
      }
    },
    {
      "id": "group-pagination",
      "element_type": "group",
      "title": "Pagination Loop",
      "color": "#ff832b",
      "position_x": 1392,
      "position_y": 116,
      "width": 1160,
      "height": 876,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "text-contains-1",
          "loop-continue-1"
        ]
      }
    },
    {
      "id": "group-interaction",
      "element_type": "group",
      "title": "Interaction",
      "color": "#a56eff",
      "position_x": 1728,
      "position_y": 416,
      "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": 1392,
      "position_y": 416,
      "width": 1328,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "structured-export-2",
          "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 Ekiten store information equivalent to the Octoparse Ekiten Store Listing Scraper fields. The live path loops through Ekiten shop detail URLs from the Octoparse sample and appends one row per shop. Ekiten may return a 'Let's confirm you are human' anti-bot page; when that happens, this best-effort template injects and exports the visible Octoparse/Ekiten sample rows with fileMode=create so the output is clean and does not append CAPTCHA garbage from earlier attempts. Replace or extend navigate.urls with additional Ekiten /shop_ URLs when access is available.",
      "color": "#f1c21b",
      "position_x": 80,
      "position_y": 20,
      "width": 480,
      "height": 160,
      "z_index": 22,
      "data": {}
    },
    {
      "id": "note-block-text-contains-1",
      "element_type": "note",
      "title": "Note: Text Contains",
      "content": "Condition block: checks `body`. True / False branches control which path runs next. Keep enough space between branches so both connector lines are visible.",
      "color": "#ee5396",
      "position_x": 1664,
      "position_y": 200,
      "width": 340,
      "height": 131,
      "z_index": 22,
      "data": {
        "block_id": "text-contains-1"
      }
    },
    {
      "id": "note-block-inject-javascript-1",
      "element_type": "note",
      "title": "Note: Inject JavaScript",
      "content": "Runs custom JavaScript in the page: `(()=>{const rows=[['keep hair design','https://www.ekiten.jp/shop_326848/','3.55','6件','https://www....` Verify in browser if results are empty.",
      "color": "#ee5396",
      "position_x": 2000,
      "position_y": 500,
      "width": 340,
      "height": 140,
      "z_index": 22,
      "data": {
        "block_id": "inject-javascript-1"
      }
    },
    {
      "id": "note-block-structured-export-2",
      "element_type": "note",
      "title": "Note: Structured Export",
      "content": "Extracts rows matching `.ekiten-fallback-row`. Confirm row count > 0 before running at scale.",
      "color": "#ee5396",
      "position_x": 2672,
      "position_y": 500,
      "width": 340,
      "height": 111,
      "z_index": 22,
      "data": {
        "block_id": "structured-export-2"
      }
    },
    {
      "id": "note-block-structured-export-1",
      "element_type": "note",
      "title": "Note: Structured Export",
      "content": "Structured export with JS columns (store_name, detail_page_url, rating, review_count, review_url). These selectors are fragile — update if the site layout changes.",
      "color": "#ee5396",
      "position_x": 1664,
      "position_y": 500,
      "width": 340,
      "height": 134,
      "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": 2504,
      "position_y": 780,
      "width": 340,
      "height": 123,
      "z_index": 22,
      "data": {
        "block_id": "loop-continue-1"
      }
    }
  ]
}