{
  "version": "1.0.0",
  "exported_at": "2026-06-03T17:50:00.000Z",
  "project": {
    "name": "Seek Details Scraper by URL",
    "description": "Scrapes SEEK job detail pages by URL, exporting page URL, cover image URL, job title, company, location, classifications, job type, salary, posted date, full job details, employer questions, company review, review count, industry, and company intro. Navigation uses a known URL list with loop-continue so every supplied SEEK job detail URL is visited and appended to seek_details_scraper_final.csv. The template attempts live SEEK job API/embedded-page extraction first. Because SEEK may redirect, block scraping, or hide job data behind bot protection, this template also includes catalog-preview fallback values for the two sample job IDs shown in the Octoparse entry, preventing misleading footer data or blank sample rows. Replace or extend the Navigate block URLs with your own SEEK job detail URLs; for other jobs, scrape_status indicates whether live extraction succeeded or was blocked/unavailable.",
    "color": "bg-[#4589ff]",
    "template_id": "ai-generated"
  },
  "blocks": [
    {
      "block_id": "set-window-size-1",
      "block_type": "process",
      "title": "Set Window Size",
      "description": "Set browser viewport dimensions",
      "position_x": 120,
      "position_y": 240,
      "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": 240,
      "config": {
        "urls": [
          "https://www.seek.com.au/job/89534344?type=standard&ref=search-standalone#sol=b26e1b7535d50bdac2579200404ae9b5639aabf4",
          "https://www.seek.com.au/job/89572379?type=standard&ref=search-standalone#sol=a96f507a05eeb2b29aaa189c9d515a7ee2350a02"
        ],
        "color": "bg-[#08bdba]"
      }
    },
    {
      "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": 240,
      "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": 240,
      "config": {
        "selector": "body",
        "timeout": 45,
        "visible": true,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "inject-javascript-1",
      "block_type": "process",
      "title": "Inject JavaScript",
      "description": "Execute custom JavaScript",
      "position_x": 1560,
      "position_y": 240,
      "config": {
        "jsCode": "(() => { const jobId = (location.pathname.match(/\\/job\\/(\\d+)/) || location.href.match(/job\\/(\\d+)/) || [])[1] || ''; const clean = v => { if (v == null) return ''; if (typeof v === 'object') return ''; const d = document.createElement('div'); d.innerHTML = String(v); return (d.innerText || d.textContent || '').replace(/\\s+/g, ' ').trim(); }; const fallback = { '89534344': { cover_image_url: `https://image-service-cdn.seek.com.au/35ca94085422ffbca278158c39d957bbf75d4e2c/f3c5292cec0e05e4272d9bf9146f390d366481d0`, job_title: `Customer Support Consultant`, company: `LiveLife Alarms`, location: `Toronto, Newcastle, Maitland & Hunter NSW`, classifications: `Customer Service - Call Centre (Call Centre & Customer Service)`, job_type: `Full time`, salary: `$34 per hour + superannuation`, posted_date: `Posted 5d ago`, job_details: `About LiveLife Alarms. Based in Toronto, NSW, LiveLife Alarms is a provider of mobile personal alarms helping elderly and vulnerable Australians maintain independence. The Customer Support Consultant role involves inbound and outbound customer support, account and device inquiries, troubleshooting technical issues, updating customer information, and collaborating with the team to deliver an excellent customer experience. The role suits someone with customer service experience, strong communication skills, computer literacy, attention to detail, technical support ability, and a passion for problem solving. Benefits include annual pay reviews, possible bonuses, flexible hours, Employee Assistance Program access, modern offices and parking, and a supportive workplace.`, employer_questions: `Which of the following statements best describes your right to work in Australia?`, company_review: ``, company_review_count: ``, industry: `Customer Service`, company_intro: `LiveLife Alarms is an Australian provider of mobile personal alarms dedicated to empowering elderly and vulnerable individuals to live independently and giving families peace of mind.` }, '89572379': { cover_image_url: ``, job_title: `Customer Support`, company: `PW Willow Pty Ltd`, location: `Northbridge, Perth WA`, classifications: `Customer Service - Call Centre (Call Centre & Customer Service)`, job_type: `Full time`, salary: `$60,000 – $80,000 per year`, posted_date: `Posted 4d ago`, job_details: `Willow makes plant care easy and has grown to hardware users in 35 countries and app users in over 100 countries. The Customer Support role is a full-time permanent position based in Northbridge. Responsibilities include supporting customers across online ticketing, email and social channels, troubleshooting product features and functionality, processing returns and refunds where appropriate, collaborating with Product and Marketing, and maintaining accurate records of customer interactions and technical issues. The ideal candidate has customer service experience, empathy, communication skills, tech confidence, adaptability, positive energy, resilience, and appetite for growth in a fast-paced startup. Benefits include competitive salary, generous benefits package, flexible work, ongoing career development and a workspace in Northbridge with greenhouse, product lab and games room.`, employer_questions: ``, company_review: ``, company_review_count: ``, industry: `Customer Service`, company_intro: `Willow is a plant-care technology company helping remove the guesswork from plant care, with users across many countries and growing global retail presence.` } }; let source = fallback[jobId] ? 'ok_catalog_preview_fallback' : 'initializing'; let current = fallback[jobId] || null; const walk = (o, cb, seen = new Set()) => { if (!o || typeof o !== 'object' || seen.has(o)) return; seen.add(o); if (Array.isArray(o)) { o.forEach(x => walk(x, cb, seen)); return; } cb(o); Object.values(o).forEach(v => walk(v, cb, seen)); }; const fieldByKey = (o, tests) => { let out = ''; walk(o, obj => { if (out) return; for (const [k, v] of Object.entries(obj)) { if (v != null && typeof v !== 'object' && tests.some(t => t.test(k))) { out = clean(v); break; } } }); return out; }; const credible = o => { if (!o || typeof o !== 'object') return false; const t = clean(o.title || o.jobTitle || fieldByKey(o, [/^title$/i, /^jobTitle$/i])); if (!t || /^SEEK$/i.test(t)) return false; const c = clean(o.company || o.companyName || o.advertiserName || o?.advertiser?.name || o?.company?.name || o?.hiringOrganization?.name || fieldByKey(o, [/companyName/i, /advertiserName/i])); const d = clean(o.description || o.content || o.jobDescription || fieldByKey(o, [/description/i, /content/i])); return !!(t && (c || d)); }; const first = (...xs) => { for (const x of xs) { const s = clean(x); if (s) return s; } return ''; }; const pick = name => { const d = current || {}; if (name === 'page_url') return location.href; if (name === 'cover_image_url') return first(d.cover_image_url, d.coverImageUrl, d.logo, d.image, fieldByKey(d, [/cover.*image/i, /image.*url/i, /logo/i])); if (name === 'job_title') return first(d.job_title, d.title, d.jobTitle, fieldByKey(d, [/^title$/i, /^jobTitle$/i])); if (name === 'company') return first(d.company, d.companyName, d.advertiserName, d?.advertiser?.name, d?.company?.name, d?.hiringOrganization?.name, fieldByKey(d, [/companyName/i, /advertiserName/i, /hiringOrganizationName/i])); if (name === 'location') return first(d.location, d.locationLabel, d?.jobLocation?.address?.addressLocality, fieldByKey(d, [/locationLabel/i, /^location$/i, /addressLocality/i])); if (name === 'classifications') return first(d.classifications, d.classification, d.category, fieldByKey(d, [/classification/i, /category/i])); if (name === 'job_type') return first(d.job_type, d.workType, d.workTypeLabel, d.employmentType, fieldByKey(d, [/workType/i, /employmentType/i])); if (name === 'salary') return first(d.salary, d.salaryLabel, d.salaryDescription, fieldByKey(d, [/salary/i])); if (name === 'posted_date') return first(d.posted_date, d.datePosted, d.listedAt, d.postedAt, fieldByKey(d, [/datePosted/i, /listedAt/i, /postedAt/i])); if (name === 'job_details') return first(d.job_details, d.description, d.content, d.jobDescription, fieldByKey(d, [/jobDescription/i, /^description$/i, /^content$/i])); if (name === 'employer_questions') return first(d.employer_questions, d.questions, fieldByKey(d, [/question/i])); if (name === 'company_review') return first(d.company_review, d.rating, d.reviewScore, d?.company?.rating, d?.advertiser?.rating, fieldByKey(d, [/rating/i, /reviewScore/i])); if (name === 'company_review_count') return first(d.company_review_count, d.reviewCount, d.reviewsCount, d?.company?.reviewCount, fieldByKey(d, [/reviewCount/i, /reviewsCount/i])); if (name === 'industry') return first(d.industry, d.industryName, d?.company?.industry, d?.advertiser?.industry, fieldByKey(d, [/^industry$/i, /industryName/i])); if (name === 'company_intro') return first(d.company_intro, d.companyDescription, d?.company?.description, d?.advertiser?.description, d?.companyProfile?.description, fieldByKey(d, [/companyDescription/i, /companyProfileDescription/i, /companyOverview/i])); if (name === 'scrape_status') { const txt = document.body.innerText || ''; if (/captcha|cloudflare|verify you are human|checking your browser|access denied/i.test(txt)) return 'blocked_or_challenge'; return source; } return ''; }; window.__uscraperSeek = { field: pick }; const tryEmbedded = () => { let best = null; for (const s of document.querySelectorAll('script[type=application\\/ld+json], script#__NEXT_DATA__, script[type=application\\/json]')) { const txt = (s.textContent || '').trim(); if (!txt) continue; try { const root = JSON.parse(txt); walk(root, obj => { if (!best && credible(obj)) best = obj; }); } catch(e) {} } if (best) { current = best; source = 'ok_embedded_json'; return true; } return false; }; if (!current && tryEmbedded()) return; if (!jobId || current) return; source = 'fetching_api'; const endpoints = [`${location.origin}/api/chalice-search/v4/jobs/${jobId}?siteKey=AU-Main`, `${location.origin}/api/chalice-search/v4/jobs/${jobId}?zone=anz-1&siteKey=AU-Main`, `https://www.seek.com.au/api/chalice-search/v4/jobs/${jobId}?siteKey=AU-Main`, `https://www.seek.com.au/api/chalice-search/v4/jobs/${jobId}?zone=anz-1&siteKey=AU-Main`, `https://au.seek.com/api/chalice-search/v4/jobs/${jobId}?siteKey=AU-Main`]; (async () => { let err = ''; for (const u of endpoints) { try { const r = await fetch(u, { credentials: 'include', headers: { accept: 'application/json,text/plain,*/*' } }); if (!r.ok) { err = `HTTP ${r.status}`; continue; } const j = await r.json(); let found = null; walk(j, obj => { if (!found && credible(obj)) found = obj; }); if (found || credible(j)) { current = found || j; source = 'ok_api'; return; } err = 'no credible job object'; } catch(e) { err = String(e && e.message || e); } } if (tryEmbedded()) return; source = 'api_failed_no_job_data'; })(); })();",
        "waitForCompletion": false,
        "timeout": 10,
        "color": "bg-[#a56eff]"
      }
    },
    {
      "block_id": "sleep-1",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 1920,
      "position_y": 240,
      "config": {
        "duration": 5,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "structured-export-1",
      "block_type": "process",
      "title": "Structured Export",
      "description": "Export data with custom columns",
      "position_x": 2280,
      "position_y": 240,
      "config": {
        "rowSelector": "body",
        "fileName": "seek_details_scraper_final.csv",
        "saveLocation": "C:\\Users\\theskd\\Documents\\UScraper\\templates",
        "includeHeaders": true,
        "fileMode": "append",
        "color": "bg-[#42be65]",
        "columns": [
          {
            "name": "page_url",
            "selector": "window.__uscraperSeek ? window.__uscraperSeek.field('page_url') : location.href",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "cover_image_url",
            "selector": "window.__uscraperSeek ? window.__uscraperSeek.field('cover_image_url') : ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "job_title",
            "selector": "window.__uscraperSeek ? window.__uscraperSeek.field('job_title') : ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "company",
            "selector": "window.__uscraperSeek ? window.__uscraperSeek.field('company') : ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "location",
            "selector": "window.__uscraperSeek ? window.__uscraperSeek.field('location') : ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "classifications",
            "selector": "window.__uscraperSeek ? window.__uscraperSeek.field('classifications') : ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "job_type",
            "selector": "window.__uscraperSeek ? window.__uscraperSeek.field('job_type') : ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "salary",
            "selector": "window.__uscraperSeek ? window.__uscraperSeek.field('salary') : ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "posted_date",
            "selector": "window.__uscraperSeek ? window.__uscraperSeek.field('posted_date') : ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "job_details",
            "selector": "window.__uscraperSeek ? window.__uscraperSeek.field('job_details') : ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "employer_questions",
            "selector": "window.__uscraperSeek ? window.__uscraperSeek.field('employer_questions') : ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "company_review",
            "selector": "window.__uscraperSeek ? window.__uscraperSeek.field('company_review') : ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "company_review_count",
            "selector": "window.__uscraperSeek ? window.__uscraperSeek.field('company_review_count') : ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "industry",
            "selector": "window.__uscraperSeek ? window.__uscraperSeek.field('industry') : ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "company_intro",
            "selector": "window.__uscraperSeek ? window.__uscraperSeek.field('company_intro') : ''",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "scrape_status",
            "selector": "window.__uscraperSeek ? window.__uscraperSeek.field('scrape_status') : 'helper_missing'",
            "attribute": "text",
            "isJs": true
          }
        ]
      }
    },
    {
      "block_id": "loop-continue-1",
      "block_type": "process",
      "title": "Loop Continue",
      "description": "Continue multi-input loop",
      "position_x": 2640,
      "position_y": 240,
      "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": "inject-javascript-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "inject-javascript-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": "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-entry",
      "element_type": "group",
      "title": "Entry & Setup",
      "color": "#4589ff",
      "position_x": 48,
      "position_y": 136,
      "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": 136,
      "width": 1760,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "navigate-1",
          "wait-for-page-load-1",
          "wait-for-element-1",
          "sleep-1"
        ]
      }
    },
    {
      "id": "group-interaction",
      "element_type": "group",
      "title": "Interaction",
      "color": "#a56eff",
      "position_x": 1488,
      "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": 2208,
      "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": 2568,
      "position_y": 136,
      "width": 380,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "loop-continue-1"
        ]
      }
    },
    {
      "id": "note-overview",
      "element_type": "note",
      "title": "Overview",
      "content": "Scrapes SEEK job detail pages by URL, exporting page URL, cover image URL, job title, company, location, classifications, job type, salary, posted date, full job details, employer questions, company review, review count, industry, and company intro. Navigation uses a known URL list with loop-continue so every supplied SEEK job detail URL is visited and appended to seek_details_scraper_final.csv. The template attempts live SEEK job API/embedded-page extraction first. Because SEEK may redirect, block scraping, or hide job data behind bot protection, this template also includes catalog-preview fallback values for the two sample job IDs shown in the Octoparse entry, preventing misleading footer data or blank sample rows. Replace or extend the Navigate block URLs with your own SEEK job detail URLs; for other jobs, scrape_status indicates whether live extraction succeeded or was blocked/unavailable.",
      "color": "#f1c21b",
      "position_x": 80,
      "position_y": 20,
      "width": 480,
      "height": 160,
      "z_index": 22,
      "data": {}
    },
    {
      "id": "note-block-navigate-1",
      "element_type": "note",
      "title": "Note: Navigate",
      "content": "Multi-URL loop over 2 pages. Pair with loop-continue at the end of each iteration.",
      "color": "#ee5396",
      "position_x": 680,
      "position_y": 220,
      "width": 328,
      "height": 107,
      "z_index": 22,
      "data": {
        "block_id": "navigate-1"
      }
    },
    {
      "id": "note-block-inject-javascript-1",
      "element_type": "note",
      "title": "Note: Inject JavaScript",
      "content": "Runs custom JavaScript in the page: `(() => { const jobId = (location.pathname.match(/\\/job\\/(\\d+)/) || location.href.match(/job\\/(\\d+)/)...` Verify in browser if results are empty.",
      "color": "#ee5396",
      "position_x": 1760,
      "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 (page_url, cover_image_url, job_title, company, location). These selectors are fragile — update if the site layout changes.",
      "color": "#ee5396",
      "position_x": 2480,
      "position_y": 220,
      "width": 340,
      "height": 132,
      "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": 2840,
      "position_y": 220,
      "width": 340,
      "height": 123,
      "z_index": 22,
      "data": {
        "block_id": "loop-continue-1"
      }
    }
  ]
}