{
  "version": "1.0.0",
  "exported_at": "2026-06-03T20:20:00.000Z",
  "project": {
    "name": "Doda Job Detail Scraper",
    "description": "Extracts Doda job-detail data such as company name, tags, company overview, address, contact details, homepage, job description, requirements, workplace, employment type, salary, benefits, holidays, posting period, update date, and URL. This is a detail-page URL-loop scraper: add active Doda job detail URLs to navigate.urls and the template appends one CSV row per URL. Individual Doda job detail pages do not have pagination. The analyzed sample URL currently returns an expired/HTTP 410 job page; expired pages are marked as 掲載終了 and do not export navigation/footer text.",
    "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": 240,
      "config": {
        "urls": [
          "https://doda.jp/DodaFront/View/JobSearchDetail/j_jid__3014578639/-tab__jd/"
        ],
        "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": 480,
      "position_y": 240,
      "config": {
        "timeout": 30
      }
    },
    {
      "block_id": "wait-for-element-1",
      "block_type": "process",
      "title": "Wait for Element",
      "description": "Wait until element appears",
      "position_x": 840,
      "position_y": 240,
      "config": {
        "selector": "body",
        "timeout": 30,
        "visible": true
      }
    },
    {
      "block_id": "inject-javascript-1",
      "block_type": "process",
      "title": "Inject JavaScript",
      "description": "Execute custom JavaScript",
      "position_x": 1200,
      "position_y": 240,
      "config": {
        "jsCode": "(function(){const clean=s=>(s||'').replace(/\\u00a0/g,' ').replace(/\\s+/g,' ').trim();window.US_DODA_CLEAN=clean;window.US_DODA_EXPIRED=function(){return /ご指定の求人情報は掲載が終了|掲載が終了しております/.test(document.body.innerText||'');};function root(){return document.querySelector('main,#content,#contents,#container,.content1200,[class*=\"job\" i],[class*=\"detail\" i]')||document.body;}function after(e){if(!e)return '';let n=e.nextElementSibling;if(n){let v=clean(n.innerText||n.textContent);if(v)return v;}let tr=e.closest('tr');if(tr){let cell=e.closest('th,td')||e;let a=[...tr.children],i=a.indexOf(cell),v=clean(a.slice(i+1).map(x=>x.innerText||x.textContent).join(' '));if(v)return v;}let dt=e.closest('dt');if(dt){let dd=dt.nextElementSibling;if(dd&&dd.tagName==='DD'){let v=clean(dd.innerText||dd.textContent);if(v)return v;}}let p=e.parentElement;if(p){let txt=clean(p.innerText||p.textContent),lab=clean(e.innerText||e.textContent);if(txt.startsWith(lab)){let v=clean(txt.slice(lab.length).replace(/^[：:\\s]+/,''));if(v)return v;}}return '';}window.US_DODA_FIELD=function(labels){if(window.US_DODA_EXPIRED())return '';labels=Array.isArray(labels)?labels:[labels];let nodes=[...root().querySelectorAll('th,dt,h1,h2,h3,h4,h5,p,div,span')];for(const label of labels){for(const e of nodes){let own=clean([...e.childNodes].filter(n=>n.nodeType===3).map(n=>n.textContent).join(''))||clean(e.textContent);let norm=own.replace(/[：:]/g,'');if(norm===label){let v=after(e);if(v)return v;}if(own.startsWith(label+'：')||own.startsWith(label+':')){let v=clean(own.slice(label.length).replace(/^[：:\\s]+/,''));if(v)return v;}}}return '';};window.US_DODA_SECTION=function(labels){if(window.US_DODA_EXPIRED())return '';let v=window.US_DODA_FIELD(labels);if(v)return v;labels=Array.isArray(labels)?labels:[labels];let heads=[...root().querySelectorAll('h1,h2,h3,h4,th,dt')];for(const label of labels){let h=heads.find(e=>clean(e.textContent).replace(/[：:]/g,'').includes(label));if(h){let out=[],n=h.nextElementSibling;while(n&&out.length<10&&!/^H[1-3]$/.test(n.tagName)){let t=clean(n.innerText||n.textContent);if(t)out.push(t);n=n.nextElementSibling;}if(out.length)return out.join(' ');}}return '';};window.US_DODA_EMAIL=function(){if(window.US_DODA_EXPIRED())return '';let m=(root().innerText||'').match(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}/i);return m?m[0]:'';};window.US_DODA_PHONE=function(){if(window.US_DODA_EXPIRED())return '';let m=(root().innerText||'').match(/(?:0\\d{1,4}[-ー−]?\\d{1,4}[-ー−]?\\d{3,4}|\\d{2,4}-\\d{2,4}-\\d{3,4})/);return m?m[0]:'';};window.US_DODA_ADDRESS=function(){return window.US_DODA_FIELD(['所在地','本社所在地','住所','勤務地所在地'])||'';};window.US_DODA_POSTAL=function(){if(window.US_DODA_EXPIRED())return '';let m=(window.US_DODA_ADDRESS()+' '+root().innerText).match(/(?:〒\\s*)?(\\d{3}-\\d{4})/);return m?m[1]:'';};window.US_DODA_PREF=function(){let a=window.US_DODA_ADDRESS();let m=a.match(/(北海道|東京都|京都府|大阪府|.{2,3}県)/);return m?m[1]:'';};window.US_DODA_CITY=function(){let a=window.US_DODA_ADDRESS(),p=window.US_DODA_PREF();if(!p)return '';let r=a.slice(a.indexOf(p)+p.length).match(/([^\\s　,、]+?[市区町村])/);return r?r[1]:'';};window.US_DODA_HP=function(){if(window.US_DODA_EXPIRED())return '';let v=window.US_DODA_FIELD(['HP','ホームページ','企業URL','会社URL']);if(/^https?:\\/\\//.test(v))return v;let scope=root();let a=[...scope.querySelectorAll('a[href^=\"http\"]')].find(x=>!x.href.includes('doda.jp')&&!x.href.includes('persol')&&!x.href.includes('privacymark.jp')&&!x.href.includes('javascript'));return a?a.href:'';};window.US_DODA_TAGS=function(){if(window.US_DODA_EXPIRED())return '';let scope=root();return Array.from(scope.querySelectorAll('[class*=\"tag\" i],[class*=\"label\" i],[class*=\"badge\" i],[class*=\"ico\" i]')).map(e=>clean(e.innerText||e.textContent)).filter(Boolean).filter(v=>!/(会員登録|ログイン|会員専用|気になる|お知らせ|さらに読み込む)/.test(v)).filter((v,i,a)=>a.indexOf(v)===i).join(' ');};})();",
        "waitForCompletion": true,
        "timeout": 10
      }
    },
    {
      "block_id": "structured-export-1",
      "block_type": "process",
      "title": "Structured Export",
      "description": "Export data with custom columns",
      "position_x": 1560,
      "position_y": 240,
      "config": {
        "rowSelector": "body",
        "fileName": "doda_job_detail_scraper.csv",
        "saveLocation": "C:\\Users\\theskd\\Documents\\UScraper\\templates",
        "includeHeaders": true,
        "fileMode": "append",
        "columns": [
          {
            "name": "企業名",
            "selector": "window.US_DODA_FIELD(['企業名','会社名','社名'])",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "ラベル",
            "selector": "window.US_DODA_EXPIRED() ? '掲載終了' : (window.US_DODA_FIELD(['ラベル','求人名','職種名','募集職種','タイトル']) || window.US_DODA_CLEAN(document.querySelector('h1')?.innerText || ''))",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "タグ",
            "selector": "window.US_DODA_TAGS()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "事業概要",
            "selector": "window.US_DODA_SECTION(['事業概要','事業内容','会社概要'])",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "所在地",
            "selector": "window.US_DODA_ADDRESS()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "郵便番号",
            "selector": "window.US_DODA_POSTAL()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "都道府県",
            "selector": "window.US_DODA_PREF()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "市町村",
            "selector": "window.US_DODA_CITY()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "連絡先",
            "selector": "window.US_DODA_SECTION(['連絡先','問い合わせ先','問合せ先','採用担当'])",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "電話番号",
            "selector": "window.US_DODA_FIELD(['電話番号','TEL','代表電話番号']) || window.US_DODA_PHONE()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "メールアドレス",
            "selector": "window.US_DODA_FIELD(['メールアドレス','E-mail','Email']) || window.US_DODA_EMAIL()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "HP",
            "selector": "window.US_DODA_HP()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "設立年数",
            "selector": "window.US_DODA_FIELD(['設立年数','設立','設立年月','設立日'])",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "代表者",
            "selector": "window.US_DODA_FIELD(['代表者','代表取締役','代表者名'])",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "従業員数",
            "selector": "window.US_DODA_FIELD(['従業員数','社員数'])",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "資本金",
            "selector": "window.US_DODA_FIELD(['資本金'])",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "売上高",
            "selector": "window.US_DODA_FIELD(['売上高','売上'])",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "仕事内容",
            "selector": "window.US_DODA_SECTION(['仕事内容','具体的な仕事内容','募集要項'])",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "対象となる方",
            "selector": "window.US_DODA_SECTION(['対象となる方','応募資格','求める人材','必須条件'])",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "勤務地",
            "selector": "window.US_DODA_SECTION(['勤務地','勤務地詳細','勤務地一覧'])",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "雇用形態",
            "selector": "window.US_DODA_SECTION(['雇用形態'])",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "給与",
            "selector": "window.US_DODA_SECTION(['給与','賃金形態','月給','年俸'])",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "待遇_福利厚生",
            "selector": "window.US_DODA_SECTION(['待遇・福利厚生','待遇_福利厚生','福利厚生','各種制度'])",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "休日_休暇",
            "selector": "window.US_DODA_SECTION(['休日・休暇','休日_休暇','年間休日'])",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "掲載予定期間",
            "selector": "window.US_DODA_FIELD(['掲載予定期間','掲載期間'])",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "更新日",
            "selector": "window.US_DODA_FIELD(['更新日']) || (window.US_DODA_EXPIRED() ? '' : (((document.body.innerText||'').match(/更新日[：:]?\\s*([^\\n]+)/)||[])[1] || ''))",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "URL",
            "selector": "location.href",
            "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": 240,
      "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": "inject-javascript-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "inject-javascript-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": 136,
      "width": 1040,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "navigate-1",
          "wait-for-page-load-1",
          "wait-for-element-1"
        ]
      }
    },
    {
      "id": "group-interaction",
      "element_type": "group",
      "title": "Interaction",
      "color": "#a56eff",
      "position_x": 1128,
      "position_y": 136,
      "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": 1488,
      "position_y": 136,
      "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": 136,
      "width": 380,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "loop-continue-1"
        ]
      }
    },
    {
      "id": "note-overview",
      "element_type": "note",
      "title": "Overview",
      "content": "Extracts Doda job-detail data such as company name, tags, company overview, address, contact details, homepage, job description, requirements, workplace, employment type, salary, benefits, holidays, posting period, update date, and URL. This is a detail-page URL-loop scraper: add active Doda job detail URLs to navigate.urls and the template appends one CSV row per URL. Individual Doda job detail pages do not have pagination. The analyzed sample URL currently returns an expired/HTTP 410 job page; expired pages are marked as 掲載終了 and do not export navigation/footer text.",
      "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: `(function(){const clean=s=>(s||'').replace(/\\u00a0/g,' ').replace(/\\s+/g,' ').trim();window.US_DODA_...` Verify in browser if results are empty.",
      "color": "#ee5396",
      "position_x": 1400,
      "position_y": 220,
      "width": 340,
      "height": 140,
      "z_index": 22,
      "data": {
        "block_id": "inject-javascript-1"
      }
    },
    {
      "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": 1760,
      "position_y": 220,
      "width": 340,
      "height": 121,
      "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": 220,
      "width": 340,
      "height": 123,
      "z_index": 22,
      "data": {
        "block_id": "loop-continue-1"
      }
    }
  ]
}