Parsing Logic That Extracts Job Requirements from CLI Detail Output

The CLI detail command extracts job requirements by parsing HTML job postings using a dual-path strategy: first attempting JSON-LD schema extraction, then falling back to manual DOM parsing to populate the description field where requirements are stored.

The parsing logic that extracts job requirements from CLI detail output operates within the MadsLorentzen/ai-job-search repository, specifically within the jobdanmark-search CLI tool. This command transforms raw HTML job postings into structured JSON objects, with the description field containing the full job text including requirements.

Fetching and Parsing the HTML Source

The extraction begins with an HTTP request and DOM construction.

Retrieving the Job Posting Page

In .agents/skills/jobdanmark-search/cli/src/commands/detail.ts at lines 14-22, the command sends a GET request to https://jobdanmark.dk/job/<slug> to fetch the raw HTML content.

Building the DOM Tree

The code uses node-html-parser to create a traversable DOM representation (parse(html)), referenced at line 90 in detail.ts. This tree enables both structured data extraction and manual element querying.

Dual-Path Extraction Strategy

The parsing logic implements a priority-based fallback system to maximize data accuracy.

JSON-LD Schema Extraction (Primary Path)

findJobPostingJsonLd scans all <script type="application/ld+json"> tags, parsing each block and returning the first object where isJobPosting validates the @type property as JobPosting (lines 85-87).

fromJsonLd then maps these structured fields directly onto the DetailResult type—including title, datePosted, employmentType, and description—as implemented at lines 89-99.

Rendered HTML Extraction (Fallback Path)

When JSON-LD is absent, fromRenderedHtml manually extracts fields using CSS selectors:

  • Job Title: Queries .job-list-details .title, falling back to <h1> or <h3> elements (lines 41-44)
  • Company Data: Extracts organization name and logo from companyLink and logoSrc selectors (lines 50-55)
  • Overview Metadata: overviewValue helper scans the job-overview list for labels like Arbejdssted, Jobtype, Udgivet, and Ansøgningsfrist (lines 22-32)
  • Description Construction: Concatenates text from all <p> and <li> nodes within .job-list-details to build the complete job description containing requirements (lines 57-61)

The Description Field: Where Requirements Reside

The description field of the resulting DetailResult object contains the full job posting text as plain text. Job requirements—such as required skills, experience levels, and qualifications—are embedded within this description.

At lines 91-92, parseJobPostingFromHtml returns the final object using either the JSON-LD or rendered-HTML path, ensuring the description is populated regardless of extraction method.

URL Normalization and CLI Output

normalizeUrl (referenced at lines 58-63) converts relative application URLs (like /apply) into absolute URLs using BASE_URL defined in the helpers file.

The command supports two output formats:

  • JSON format (--format json): Returns the complete DetailResult object
  • Plain text (--format plain): Uses outputPlain (lines 56-70) to render human-readable output

Code Examples

Fetch detailed job data including requirements:

bun run .agents/skills/jobdanmark-search/cli/src/cli.ts detail 12345 --format json

Sample output structure:

{
  "slug": "12345",
  "url": "https://jobdanmark.dk/job/12345",
  "title": "Data Engineer",
  "datePosted": "2026-07-01",
  "validThrough": "2026-07-31",
  "employmentType": ["Fuldtid"],
  "hiringOrganization": { "name": "Acme Corp", "logo": "https://…" },
  "jobLocation": { "streetAddress": "Banegårdspladsen 1, 5000 Odense C" },
  "description": "We are looking for a data engineer ... **Requirements:**\n• Strong Python knowledge …\n• Experience with ETL pipelines …",
  "applyUrl": "https://acme.career.emply.com/apply/12345"
}

Extract requirements programmatically from the description:

import { readFileSync } from "fs";

const result = JSON.parse(readFileSync("detail.json", "utf-8"));
const requirements = result.description.match(/Requirements:\s*([\s\S]*)/i)?.[1]?.trim();
console.log("Extracted requirements:\n", requirements);

Summary

  • The parsing logic extracts job requirements from the description field of the DetailResult object
  • JSON-LD extraction via findJobPostingJsonLd and fromJsonLd provides structured data when available
  • Manual HTML parsing via fromRenderedHtml serves as fallback, using overviewValue and DOM selectors
  • Key files include .agents/skills/jobdanmark-search/cli/src/commands/detail.ts and .agents/skills/jobdanmark-search/cli/src/helpers.ts
  • The node-html-parser library creates the DOM tree used for element extraction
  • Requirements remain embedded in plain text within the description field, extractable via regex or string parsing

Frequently Asked Questions

How does the detail command handle job postings without JSON-LD metadata?

When JSON-LD is absent, the code automatically falls back to fromRenderedHtml, which manually scrapes the DOM using CSS selectors like .job-list-details .title and extracts the description by concatenating <p> and <li> elements.

Where exactly are the job requirements stored in the output?

Job requirements reside within the description field of the returned DetailResult object. This field contains the complete job posting text as plain text, including sections labeled "Requirements," qualifications, and desired skills.

Can I extract structured requirement fields separately from the description?

The current implementation does not parse individual requirements into separate fields; they remain part of the unified description string. You must post-process the description using pattern matching or natural language processing to isolate specific requirements.

What dependencies does the parsing logic require?

The extraction logic relies on node-html-parser for DOM manipulation and standard Node.js HTTP clients for fetching. Helper utilities for URL normalization and text cleaning are imported from .agents/skills/jobdanmark-search/cli/src/helpers.ts.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →