{
  "version": "1.0.0",
  "exported_at": "2026-06-01T08:45:00.000Z",
  "project": {
    "name": "Hello Work Job Listings Scraper Cloud Only",
    "description": "Best-effort UScraper equivalent of the Octoparse Hello Work Job Listings Scraper. Navigates to the Hello Work search page, submits a keyword search using default keyword 営業 with full-time and part-time selected, extracts listing-level job fields, and follows the Next/次へ pagination loop until no further page is available. Edit the JavaScript search block keyword and conditions before running for other searches.",
    "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": {
        "url": "https://www.hellowork.mhlw.go.jp/kensaku/GECA110010.do?action=initDisp&screenId=GECA110010",
        "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": 456,
      "position_y": 220,
      "config": {
        "timeout": 30
      }
    },
    {
      "block_id": "inject-javascript-1",
      "block_type": "process",
      "title": "Inject JavaScript",
      "description": "Run custom JavaScript on the page",
      "position_x": 792,
      "position_y": 220,
      "config": {
        "jsCode": "(() => { const keyword = '営業'; const setChecked = (selector) => { const el = document.querySelector(selector); if (el && !el.checked) { el.click(); } }; setChecked('#ID_ippanCKBox1, input[name=\"ippanCKBox\"][value=\"1\"]'); setChecked('#ID_ippanCKBox2, input[name=\"ippanCKBox\"][value=\"2\"]'); const input = document.querySelector('#ID_freeWordInput, input[name=\"freeWordInput\"], input[name*=\"freeWord\"], input[id*=\"freeWord\"]'); if (input) { input.focus(); input.value = keyword; input.dispatchEvent(new Event('input', { bubbles: true })); input.dispatchEvent(new Event('change', { bubbles: true })); } const btn = document.querySelector('#ID_searchBtn, button[name=\"searchBtn\"], input[name=\"searchBtn\"], button[value=\"検索する\"], input[value=\"検索する\"]'); if (btn) { btn.click(); return 'clicked search button'; } const form = document.querySelector('#ID_form_1, form[name=\"form_1\"]'); if (form) { if (form.requestSubmit) { form.requestSubmit(); } else { form.submit(); } return 'submitted search form'; } return 'search control not found'; })();",
        "waitForCompletion": true,
        "timeout": 10
      }
    },
    {
      "block_id": "wait-for-page-load-2",
      "block_type": "process",
      "title": "Wait for Page Load",
      "description": "Wait for page to finish loading",
      "position_x": 1128,
      "position_y": 220,
      "config": {
        "timeout": 30
      }
    },
    {
      "block_id": "sleep-1",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 1464,
      "position_y": 220,
      "config": {
        "duration": 2
      }
    },
    {
      "block_id": "wait-for-element-1",
      "block_type": "process",
      "title": "Wait for Element",
      "description": "Wait until element appears",
      "position_x": 1800,
      "position_y": 220,
      "config": {
        "selector": "a[href*=\"dispDetailBtn\"], button[name*=\"dispDetailBtn\"], input[name*=\"dispDetailBtn\"], a[href*=\"kyujinhyoBtn\"], button[name*=\"kyujinhyoBtn\"], input[name*=\"kyujinhyoBtn\"]",
        "timeout": 30,
        "visible": true
      }
    },
    {
      "block_id": "inject-javascript-2",
      "block_type": "process",
      "title": "Inject JavaScript",
      "description": "Run custom JavaScript on the page",
      "position_x": 2136,
      "position_y": 220,
      "config": {
        "jsCode": "(() => { document.querySelectorAll('[data-uscraper-job-row=\"true\"]').forEach(el => { el.removeAttribute('data-uscraper-job-row'); el.removeAttribute('data-uscraper-row-index'); }); const controls = Array.from(document.querySelectorAll('a[href*=\"dispDetailBtn\"], button[name*=\"dispDetailBtn\"], input[name*=\"dispDetailBtn\"], a[href*=\"kyujinhyoBtn\"], button[name*=\"kyujinhyoBtn\"], input[name*=\"kyujinhyoBtn\"]')); const rows = []; for (const control of controls) { let node = control; for (let depth = 0; node && depth < 10; depth++, node = node.parentElement) { const text = (node.innerText || node.value || '').replace(/\\s+/g, ' ').trim(); if (text.includes('求人番号') && (text.includes('職種') || text.includes('仕事の内容') || text.includes('事業所名')) && text.length > 120) { rows.push(node); break; } } } const unique = []; for (const row of rows) { if (!unique.includes(row) && !unique.some(existing => existing.contains(row))) { unique.push(row); } } unique.forEach((row, index) => { row.setAttribute('data-uscraper-job-row', 'true'); row.setAttribute('data-uscraper-row-index', String(index + 1)); }); return unique.length; })();",
        "waitForCompletion": true,
        "timeout": 10
      }
    },
    {
      "block_id": "structured-export-1",
      "block_type": "process",
      "title": "Structured Export",
      "description": "Export data with custom columns",
      "position_x": 2472,
      "position_y": 220,
      "config": {
        "rowSelector": "[data-uscraper-job-row=\"true\"]",
        "fileName": "hellowork-job-listings-cloud-only-scraper.csv",
        "saveLocation": "C:\\Users\\theskd\\Documents\\UScraper\\templates",
        "includeHeaders": true,
        "fileMode": "append",
        "columns": [
          {
            "name": "職種",
            "selector": "(() => { const lines = ROW.innerText.replace(/\\u00a0/g, ' ').split(/\\n+/).map(s => s.trim()).filter(Boolean); const pick = (label, next) => { const i = lines.findIndex(l => l === label || l.startsWith(label + ' ')); if (i < 0) return ''; const out = []; const first = lines[i].replace(label, '').trim(); if (first) out.push(first); for (let j = i + 1; j < lines.length; j++) { if (next.some(n => lines[j] === n || lines[j].startsWith(n + ' '))) break; if (!['職種解説', '二次元', 'バーコード'].includes(lines[j])) out.push(lines[j]); } return out.join(' ').replace(/^職種解説\\s*/, '').trim(); }; return pick('職種', ['仕事の内容', '仕事内容', '事業所名', '就業場所', '賃金', '求人番号']); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "求人区分",
            "selector": "(() => { const text = ROW.innerText.replace(/\\s+/g, ' ').trim(); const m = text.match(/求人区分\\s*([^\\s]+(?:\\s*求人)?)/); if (m) return m[1].trim(); const badge = text.match(/(正社員|有期雇用|有期雇用パート|パート|フルタイム)/); return badge ? badge[1] : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "事業所名",
            "selector": "(() => { const lines = ROW.innerText.replace(/\\u00a0/g, ' ').split(/\\n+/).map(s => s.trim()).filter(Boolean); const pick = (label, next) => { const i = lines.findIndex(l => l === label || l.startsWith(label + ' ')); if (i < 0) return ''; const out = []; const first = lines[i].replace(label, '').trim(); if (first) out.push(first); for (let j = i + 1; j < lines.length; j++) { if (next.some(n => lines[j] === n || lines[j].startsWith(n + ' '))) break; out.push(lines[j]); } return out.join(' ').trim(); }; return pick('事業所名', ['就業場所', '仕事の内容', '仕事内容', '賃金', '求人番号']); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "就業場所",
            "selector": "(() => { const lines = ROW.innerText.replace(/\\u00a0/g, ' ').split(/\\n+/).map(s => s.trim()).filter(Boolean); const pick = (label, next) => { const i = lines.findIndex(l => l === label || l.startsWith(label + ' ')); if (i < 0) return ''; const out = []; const first = lines[i].replace(label, '').trim(); if (first) out.push(first); for (let j = i + 1; j < lines.length; j++) { if (next.some(n => lines[j] === n || lines[j].startsWith(n + ' '))) break; out.push(lines[j]); } return out.join(' ').trim(); }; return pick('就業場所', ['仕事の内容', '仕事内容', '賃金', '就業時間', '休日', '求人番号']); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "仕事の内容",
            "selector": "(() => { const lines = ROW.innerText.replace(/\\u00a0/g, ' ').split(/\\n+/).map(s => s.trim()).filter(Boolean); const pick = (labels, next) => { const i = lines.findIndex(l => labels.some(label => l === label || l.startsWith(label + ' '))); if (i < 0) return ''; const label = labels.find(label => lines[i] === label || lines[i].startsWith(label + ' ')); const out = []; const first = lines[i].replace(label, '').trim(); if (first) out.push(first); for (let j = i + 1; j < lines.length; j++) { if (next.some(n => lines[j] === n || lines[j].startsWith(n + ' '))) break; out.push(lines[j]); } return out.join(' ').trim(); }; return pick(['仕事の内容', '仕事内容'], ['雇用形態', '求人区分', '事業所名', '就業場所', '賃金', '就業時間', '休日', '求人番号']); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "雇用形態",
            "selector": "(() => { const lines = ROW.innerText.replace(/\\u00a0/g, ' ').split(/\\n+/).map(s => s.trim()).filter(Boolean); const i = lines.findIndex(l => l === '雇用形態' || l.startsWith('雇用形態 ')); if (i >= 0) { const v = lines[i].replace('雇用形態', '').trim() || lines[i + 1] || ''; return v.trim(); } const text = ROW.innerText.replace(/\\s+/g, ' '); const m = text.match(/\\b(フル|パート|フルタイム)\\b/); return m ? m[1] : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "求人数",
            "selector": "(() => { const text = ROW.innerText.replace(/\\s+/g, ' ').trim(); const m = text.match(/求人数[:：]?\\s*([0-9０-９,，]+\\s*名?)/); return m ? m[1].trim() : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "賃金_手当等を含む",
            "selector": "(() => { const lines = ROW.innerText.replace(/\\u00a0/g, ' ').split(/\\n+/).map(s => s.trim()).filter(Boolean); const i = lines.findIndex(l => l.startsWith('賃金')); if (i < 0) return ''; const out = []; for (let j = i; j < lines.length; j++) { if (j > i && ['就業時間', '休日', '求人番号', '公開範囲'].some(n => lines[j] === n || lines[j].startsWith(n + ' '))) break; out.push(lines[j].replace(/^賃金\\s*/, '').replace(/^（手当等を含む）\\s*/, '').trim()); } return out.filter(Boolean).join(' ').trim(); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "就業時間",
            "selector": "(() => { const lines = ROW.innerText.replace(/\\u00a0/g, ' ').split(/\\n+/).map(s => s.trim()).filter(Boolean); const i = lines.findIndex(l => l === '就業時間' || l.startsWith('就業時間 ')); if (i < 0) return ''; const out = []; const first = lines[i].replace('就業時間', '').trim(); if (first) out.push(first); for (let j = i + 1; j < lines.length; j++) { if (['休日', '求人番号', '公開範囲', '求人数'].some(n => lines[j] === n || lines[j].startsWith(n + ' '))) break; out.push(lines[j]); } return out.join(' ').trim(); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "休日",
            "selector": "(() => { const lines = ROW.innerText.replace(/\\u00a0/g, ' ').split(/\\n+/).map(s => s.trim()).filter(Boolean); const i = lines.findIndex(l => l === '休日' || l.startsWith('休日 ')); if (i < 0) return ''; const out = []; const first = lines[i].replace('休日', '').trim(); if (first) out.push(first); for (let j = i + 1; j < lines.length; j++) { if (['求人番号', '公開範囲', '求人数', '詳細を表示', '求人票を表示'].some(n => lines[j] === n || lines[j].startsWith(n + ' '))) break; out.push(lines[j]); } return out.join(' ').trim(); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "公開範囲",
            "selector": "(() => { const lines = ROW.innerText.replace(/\\u00a0/g, ' ').split(/\\n+/).map(s => s.trim()).filter(Boolean); const i = lines.findIndex(l => l === '公開範囲' || l.startsWith('公開範囲 ')); if (i < 0) return ''; const out = []; const first = lines[i].replace('公開範囲', '').trim(); if (first) out.push(first); for (let j = i + 1; j < lines.length; j++) { if (['求人番号', '求人数', '詳細を表示', '求人票を表示'].some(n => lines[j] === n || lines[j].startsWith(n + ' '))) break; out.push(lines[j]); } return out.join(' ').trim(); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "求人番号",
            "selector": "(() => { const text = ROW.innerText.replace(/\\s+/g, ' '); const m = text.match(/求人番号\\s*([0-9]{5}-[0-9]{8})/) || text.match(/([0-9]{5}-[0-9]{8})/); return m ? m[1] : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "求人票URL",
            "selector": "(() => { const a = ROW.querySelector('a[href*=\"kyujinhyoBtn\"], a[href*=\"kyujinhyo\"]'); return a ? a.href : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "詳細ページURL",
            "selector": "(() => { const a = ROW.querySelector('a[href*=\"dispDetailBtn\"], a[href*=\"action=dispDetailBtn\"]'); return a ? a.href : ''; })()",
            "attribute": "text",
            "isJs": true
          }
        ]
      }
    },
    {
      "block_id": "inject-javascript-3",
      "block_type": "process",
      "title": "Inject JavaScript",
      "description": "Run custom JavaScript on the page",
      "position_x": 2808,
      "position_y": 220,
      "config": {
        "jsCode": "(() => { document.querySelectorAll('[data-uscraper-next=\"true\"]').forEach(el => el.removeAttribute('data-uscraper-next')); const candidates = Array.from(document.querySelectorAll('a, button, input[type=\"submit\"], input[type=\"button\"]')).filter(el => { const text = ((el.innerText || el.value || el.getAttribute('aria-label') || '') + ' ' + (el.id || '') + ' ' + (el.name || '')).trim(); const disabled = el.disabled || el.classList.contains('disabled') || el.classList.contains('disable') || el.getAttribute('aria-disabled') === 'true'; return !disabled && (/次へ|Next|next|fwListNaviBtnNext|listNaviBtnNext/i).test(text); }); if (candidates.length) { candidates[0].setAttribute('data-uscraper-next', 'true'); return 'next marked'; } return 'no next'; })();",
        "waitForCompletion": true,
        "timeout": 10
      }
    },
    {
      "block_id": "element-exists-1",
      "block_type": "process",
      "title": "Element Exists",
      "description": "Check if element exists",
      "position_x": 3144,
      "position_y": 220,
      "config": {
        "selector": "[data-uscraper-next=\"true\"]"
      }
    },
    {
      "block_id": "click-1",
      "block_type": "process",
      "title": "Click",
      "description": "Click on element",
      "position_x": 3480,
      "position_y": 520,
      "config": {
        "selector": "[data-uscraper-next=\"true\"]",
        "timeout": 10
      }
    },
    {
      "block_id": "wait-for-page-load-3",
      "block_type": "process",
      "title": "Wait for Page Load",
      "description": "Wait for page to finish loading",
      "position_x": 3816,
      "position_y": 520,
      "config": {
        "timeout": 30
      }
    },
    {
      "block_id": "sleep-2",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 4152,
      "position_y": 520,
      "config": {
        "duration": 2
      }
    },
    {
      "block_id": "wait-for-element-2",
      "block_type": "process",
      "title": "Wait for Element",
      "description": "Wait until element appears",
      "position_x": 4488,
      "position_y": 520,
      "config": {
        "selector": "a[href*=\"dispDetailBtn\"], button[name*=\"dispDetailBtn\"], input[name*=\"dispDetailBtn\"], a[href*=\"kyujinhyoBtn\"], button[name*=\"kyujinhyoBtn\"], input[name*=\"kyujinhyoBtn\"]",
        "timeout": 30,
        "visible": true
      }
    },
    {
      "block_id": "inject-javascript-4",
      "block_type": "process",
      "title": "Inject JavaScript",
      "description": "Run custom JavaScript on the page",
      "position_x": 4824,
      "position_y": 520,
      "config": {
        "jsCode": "(() => { document.querySelectorAll('[data-uscraper-job-row=\"true\"]').forEach(el => { el.removeAttribute('data-uscraper-job-row'); el.removeAttribute('data-uscraper-row-index'); }); const controls = Array.from(document.querySelectorAll('a[href*=\"dispDetailBtn\"], button[name*=\"dispDetailBtn\"], input[name*=\"dispDetailBtn\"], a[href*=\"kyujinhyoBtn\"], button[name*=\"kyujinhyoBtn\"], input[name*=\"kyujinhyoBtn\"]')); const rows = []; for (const control of controls) { let node = control; for (let depth = 0; node && depth < 10; depth++, node = node.parentElement) { const text = (node.innerText || node.value || '').replace(/\\s+/g, ' ').trim(); if (text.includes('求人番号') && (text.includes('職種') || text.includes('仕事の内容') || text.includes('事業所名')) && text.length > 120) { rows.push(node); break; } } } const unique = []; for (const row of rows) { if (!unique.includes(row) && !unique.some(existing => existing.contains(row))) { unique.push(row); } } unique.forEach((row, index) => { row.setAttribute('data-uscraper-job-row', 'true'); row.setAttribute('data-uscraper-row-index', String(index + 1)); }); return unique.length; })();",
        "waitForCompletion": true,
        "timeout": 10
      }
    },
    {
      "block_id": "end-1",
      "block_type": "output",
      "title": "End",
      "description": "Terminate execution flow",
      "position_x": 3144,
      "position_y": 520,
      "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": "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-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-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "inject-javascript-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": "inject-javascript-3",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "inject-javascript-3",
      "from_connector_id": "right",
      "to_block_id": "element-exists-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-1",
      "from_connector_id": "true",
      "to_block_id": "click-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-1",
      "from_connector_id": "false",
      "to_block_id": "end-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "click-1",
      "from_connector_id": "right",
      "to_block_id": "wait-for-page-load-3",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "wait-for-page-load-3",
      "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": "wait-for-element-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "wait-for-element-2",
      "from_connector_id": "right",
      "to_block_id": "inject-javascript-4",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "inject-javascript-4",
      "from_connector_id": "right",
      "to_block_id": "structured-export-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": 4688,
      "height": 596,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "navigate-1",
          "wait-for-page-load-1",
          "wait-for-page-load-2",
          "sleep-1",
          "wait-for-element-1",
          "wait-for-page-load-3",
          "sleep-2",
          "wait-for-element-2"
        ]
      }
    },
    {
      "id": "group-interaction",
      "element_type": "group",
      "title": "Interaction",
      "color": "#a56eff",
      "position_x": 720,
      "position_y": 116,
      "width": 4352,
      "height": 596,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "inject-javascript-1",
          "inject-javascript-2",
          "inject-javascript-3",
          "inject-javascript-4"
        ]
      }
    },
    {
      "id": "group-extract",
      "element_type": "group",
      "title": "Data Extraction",
      "color": "#42be65",
      "position_x": 2400,
      "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": 3072,
      "position_y": 116,
      "width": 656,
      "height": 596,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "element-exists-1",
          "click-1"
        ]
      }
    },
    {
      "id": "group-control",
      "element_type": "group",
      "title": "Control Flow",
      "color": "#8d8d8d",
      "position_x": 3072,
      "position_y": 416,
      "width": 380,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "end-1"
        ]
      }
    },
    {
      "id": "note-overview",
      "element_type": "note",
      "title": "Overview",
      "content": "Best-effort UScraper equivalent of the Octoparse Hello Work Job Listings Scraper. Navigates to the Hello Work search page, submits a keyword search using default keyword 営業 with full-time and part-time selected, extracts listing-level job fields, and follows the Next/次へ pagination loop until no further page is available. Edit the JavaScript search block keyword and conditions before running for other searches.",
      "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: `(() => { const keyword = '営業'; const setChecked = (selector) => { const el = document.querySelector(...` Verify in browser if results are empty.",
      "color": "#ee5396",
      "position_x": 992,
      "position_y": 200,
      "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: `(() => { document.querySelectorAll('[data-uscraper-job-row=\"true\"]').forEach(el => { el.removeAttrib...` Verify in browser if results are empty.",
      "color": "#ee5396",
      "position_x": 2336,
      "position_y": 200,
      "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": "Structured export with JS columns (職種, 求人区分, 事業所名, 就業場所, 仕事の内容). These selectors are fragile — update if the site layout changes.",
      "color": "#ee5396",
      "position_x": 2672,
      "position_y": 200,
      "width": 340,
      "height": 123,
      "z_index": 22,
      "data": {
        "block_id": "structured-export-1"
      }
    },
    {
      "id": "note-block-inject-javascript-3",
      "element_type": "note",
      "title": "Note: Inject JavaScript",
      "content": "Runs custom JavaScript in the page: `(() => { document.querySelectorAll('[data-uscraper-next=\"true\"]').forEach(el => el.removeAttribute('...` Verify in browser if results are empty.",
      "color": "#ee5396",
      "position_x": 3008,
      "position_y": 200,
      "width": 340,
      "height": 140,
      "z_index": 22,
      "data": {
        "block_id": "inject-javascript-3"
      }
    },
    {
      "id": "note-block-element-exists-1",
      "element_type": "note",
      "title": "Note: Element Exists",
      "content": "Condition block: checks `[data-uscraper-next=\"true\"]`. True / False branches control which path runs next. Keep enough space between branches so both connector lines are visible.",
      "color": "#ee5396",
      "position_x": 3344,
      "position_y": 200,
      "width": 340,
      "height": 139,
      "z_index": 22,
      "data": {
        "block_id": "element-exists-1"
      }
    },
    {
      "id": "note-block-click-1",
      "element_type": "note",
      "title": "Note: Click",
      "content": "Pagination click — add waits after this block; the page reloads asynchronously.",
      "color": "#ee5396",
      "position_x": 3680,
      "position_y": 500,
      "width": 316,
      "height": 106,
      "z_index": 22,
      "data": {
        "block_id": "click-1"
      }
    },
    {
      "id": "note-block-inject-javascript-4",
      "element_type": "note",
      "title": "Note: Inject JavaScript",
      "content": "Runs custom JavaScript in the page: `(() => { document.querySelectorAll('[data-uscraper-job-row=\"true\"]').forEach(el => { el.removeAttrib...` Verify in browser if results are empty.",
      "color": "#ee5396",
      "position_x": 5024,
      "position_y": 500,
      "width": 340,
      "height": 140,
      "z_index": 22,
      "data": {
        "block_id": "inject-javascript-4"
      }
    }
  ]
}