{
  "version": "1.0.0",
  "exported_at": "2026-06-03T13:45:00.000Z",
  "project": {
    "name": "AMBI Job Listings Scraper",
    "description": "Extracts AMBI Japan job-detail data equivalent to the Octoparse AMBI template: 掲載期間, タイトル, 詳細ページURL, タイプ, 会社名, 年収, 勤務地, タグ, どんな仕事か1, and 会社概要. Navigation uses a multi-URL loop over supplied AMBI job detail URLs and appends results to one CSV. Pages that no longer exist or show AMBI error content are skipped when no job heading is found.",
    "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://en-ambi.com/job/j-9398163/",
          "https://en-ambi.com/job/j-11157266/",
          "https://en-ambi.com/job/j-11620581/"
        ],
        "color": "bg-[#4589ff]",
        "tags": [
          "ambi",
          "jobs",
          "multi-url"
        ]
      }
    },
    {
      "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,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "sleep-1",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 792,
      "position_y": 220,
      "config": {
        "duration": 1,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "element-exists-1",
      "block_type": "process",
      "title": "Element Exists",
      "description": "Check if element exists",
      "position_x": 1128,
      "position_y": 220,
      "config": {
        "selector": "h1",
        "color": "bg-[#ff832b]"
      }
    },
    {
      "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": "ambi-job-listings-scraper.csv",
        "saveLocation": "C:\\Users\\theskd\\Documents\\UScraper\\templates",
        "includeHeaders": true,
        "fileMode": "append",
        "color": "bg-[#42be65]",
        "columns": [
          {
            "name": "掲載期間",
            "selector": "(() => { const t = ROW.innerText.replace(/\\s+/g, ' '); const m = t.match(/掲載期間\\s*([0-9]{2}\\/[0-9]{2}\\/[0-9]{2}\\s*[～〜~-]\\s*[0-9]{2}\\/[0-9]{2}\\/[0-9]{2})/); return m ? m[1].trim() : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "タイトル",
            "selector": "(() => { const h = ROW.querySelector('h1'); if (h && h.textContent.trim()) return h.textContent.trim(); const c = ROW.querySelector('#endAnnounce .catch'); if (c && c.textContent.trim()) return c.textContent.trim(); const og = document.querySelector('meta[property=\"og:title\"]'); return og ? og.content.replace(/\\d+｜.*$/, '').trim() : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "詳細ページURL",
            "selector": "(() => location.href.split('?')[0])()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "タイプ",
            "selector": "(() => { const h = ROW.querySelector('h2'); return h ? h.textContent.trim() : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "会社名",
            "selector": "(() => { const c = ROW.querySelector('a.companyName'); if (c && c.textContent.trim()) return c.textContent.trim(); const t = ROW.innerText.replace(/\\s+/g, ' '); const h2 = ROW.querySelector('h2') ? ROW.querySelector('h2').textContent.trim() : ''; const i = h2 ? t.indexOf(h2) : -1; const s = i >= 0 ? t.slice(i, i + 300) : t; const m = s.match(/(?:株式会社|合同会社|有限会社)[^\\s　]+|[^\\s　]+(?:株式会社|合同会社|有限会社)/); return m ? m[0].trim() : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "年収",
            "selector": "(() => { const t = ROW.innerText.replace(/\\s+/g, ' '); const c = ROW.querySelector('a.companyName') ? ROW.querySelector('a.companyName').textContent.trim() : ''; const start = c && t.indexOf(c) >= 0 ? t.indexOf(c) : 0; const s = t.slice(start, start + 900); const m = s.match(/年収\\s*([0-9,]+万円\\s*[～〜~-]\\s*[0-9,]+万円)/); return m ? m[1].replace(/\\s+/g, ' ').trim() : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "勤務地",
            "selector": "(() => { const vals = Array.from(ROW.querySelectorAll('a')).filter(a => (a.getAttribute('href') || '').includes('/area/')).map(a => a.textContent.trim()).filter(Boolean); return Array.from(new Set(vals)).join('、'); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "タグ",
            "selector": "(() => { const vals = Array.from(ROW.querySelectorAll('a')).filter(a => (a.getAttribute('href') || '').includes('/color/')).map(a => a.textContent.trim()).filter(Boolean); return Array.from(new Set(vals)).join(', '); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "どんな仕事か1",
            "selector": "(() => { const t = ROW.innerText.replace(/\\s+/g, ' '); const m = t.match(/どんな仕事か\\s*(.*?)(?:応募資格|必要な経験|この仕事に向いている人|雇用形態|勤務地|年収|待遇・福利厚生|休日休暇|会社概要)/); return m ? m[1].replace(/\\s+/g, ' ').trim() : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "会社概要",
            "selector": "(() => { const t = ROW.innerText.replace(/\\s+/g, ' '); let m = t.match(/会社概要\\s*(.*?)(?:設立|資本金|従業員数|事業内容|この求人|求人No|$)/); let v = m ? m[1].trim() : ''; if (!v || v.length < 10) { m = t.match(/事業内容\\s*(.*?)(?:設立|資本金|従業員数|この求人|求人No|$)/); v = m ? m[1].trim() : v; } return v.replace(/\\s+/g, ' ').trim(); })()",
            "attribute": "text",
            "isJs": true
          }
        ]
      }
    },
    {
      "block_id": "loop-continue-1",
      "block_type": "process",
      "title": "Loop Continue",
      "description": "Continue multi-input loop",
      "position_x": 1800,
      "position_y": 520,
      "config": {
        "color": "bg-[#8d8d8d]"
      }
    }
  ],
  "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": "element-exists-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-1",
      "from_connector_id": "true",
      "to_block_id": "structured-export-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-1",
      "from_connector_id": "false",
      "to_block_id": "loop-continue-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": 116,
      "width": 992,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "navigate-1",
          "wait-for-page-load-1",
          "sleep-1"
        ]
      }
    },
    {
      "id": "group-pagination",
      "element_type": "group",
      "title": "Pagination Loop",
      "color": "#ff832b",
      "position_x": 1056,
      "position_y": 116,
      "width": 992,
      "height": 596,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "element-exists-1",
          "loop-continue-1"
        ]
      }
    },
    {
      "id": "group-extract",
      "element_type": "group",
      "title": "Data Extraction",
      "color": "#42be65",
      "position_x": 1392,
      "position_y": 416,
      "width": 380,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "structured-export-1"
        ]
      }
    },
    {
      "id": "note-overview",
      "element_type": "note",
      "title": "Overview",
      "content": "Extracts AMBI Japan job-detail data equivalent to the Octoparse AMBI template: 掲載期間, タイトル, 詳細ページURL, タイプ, 会社名, 年収, 勤務地, タグ, どんな仕事か1, and 会社概要. Navigation uses a multi-URL loop over supplied AMBI job detail URLs and appends results to one CSV. Pages that no longer exist or show AMBI error content are skipped when no job heading is found.",
      "color": "#f1c21b",
      "position_x": 80,
      "position_y": 20,
      "width": 480,
      "height": 160,
      "z_index": 22,
      "data": {}
    },
    {
      "id": "note-block-element-exists-1",
      "element_type": "note",
      "title": "Note: Element Exists",
      "content": "Condition block: checks `h1`. True / False branches control which path runs next. Keep enough space between branches so both connector lines are visible.",
      "color": "#ee5396",
      "position_x": 1328,
      "position_y": 200,
      "width": 340,
      "height": 131,
      "z_index": 22,
      "data": {
        "block_id": "element-exists-1"
      }
    },
    {
      "id": "note-block-structured-export-1",
      "element_type": "note",
      "title": "Note: Structured Export",
      "content": "Structured export with JS columns (掲載期間, タイトル, 詳細ページURL, タイプ, 会社名). These selectors are fragile — update if the site layout changes.",
      "color": "#ee5396",
      "position_x": 1664,
      "position_y": 500,
      "width": 340,
      "height": 124,
      "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": 2000,
      "position_y": 500,
      "width": 340,
      "height": 123,
      "z_index": 22,
      "data": {
        "block_id": "loop-continue-1"
      }
    }
  ]
}