
Daangn Jobs Search
Query 당근마켓 (Daangn) job listings by Korean region and keyword from a scriptable agent or terminal workflow.
Overview
Daangn Jobs Search is an agent skill for the Grow phase that fetches 당근마켓 job listings by region and search terms through a Python CLI integration.
Install
npx skills add https://github.com/nomadamas/k-skill --skill daangn-jobs-searchWhat is this skill?
- Resolves Korean region strings via Daangn regions keyword API with Seoul depth-3 fallback logic
- Fetches job listings with urllib-based JSON/HTML access and formatted wage display
- CLI-oriented Python entrypoint suitable for agent-invoked regional job scans
- Headless HTTP workflow without requiring a browser automation stack
Adoption & trust: 598 installs on skills.sh; 5.4k GitHub stars; 2/3 security scanners passed (skills.sh audits).
What problem does it solve?
You need current local job posts in Korea on Daangn but manually browsing the app does not fit an automated agent or repeatable hiring check.
Who is it for?
Korea-based solo founders or agents automating periodic scans of Daangn jobs for contractors, part-time help, or local ops roles.
Skip if: Teams outside Daangn’s market, employers needing applicant tracking APIs, or workflows that require authenticated employer dashboards.
When should I use this skill?
You need Daangn job listings for a Korean region keyword in an automated or agent-driven hiring scan.
What do I get? / Deliverables
You get JSON or formatted listing output for a resolved region so you can compare wages and titles before contacting candidates.
- Resolved region metadata for the search
- Job listing records with formatted wage fields where available
Recommended Skills
Journey fit
Grow is the canonical shelf because the skill supports hiring, contracting, and local talent discovery as the product scales beyond solo execution. Lifecycle covers recurring people ops—refreshing local job markets when you add roles or outsource deliverables.
How it compares
Regional listing fetcher script—not a full HRIS, LinkedIn-scale search, or journey-wide hiring methodology skill.
Common Questions / FAQ
Who is daangn-jobs-search for?
Builders and agents who hire or contract in Korea and want scriptable Daangn job discovery from the terminal or agent host.
When should I use daangn-jobs-search?
Use it during Grow when you are staffing lifecycle tasks—finding local help for support, content, delivery, or ops—and need refreshed listings for a specific district keyword.
Is daangn-jobs-search safe to install?
Treat it as code that calls third-party web APIs; review the Security Audits panel on this Prism page and verify you comply with Daangn terms before automating requests at scale.
SKILL.md
READMESKILL.md - Daangn Jobs Search
#!/usr/bin/env python3 import argparse, json, re, sys, urllib.parse, urllib.request from html import unescape HEADERS = {"User-Agent":"Mozilla/5.0", "Accept":"application/json,text/html;q=0.9,*/*;q=0.8"} def fetch_json(url): req = urllib.request.Request(url, headers=HEADERS) with urllib.request.urlopen(req, timeout=25) as r: body = r.read() if not body: raise ValueError(f'빈 JSON 응답: {url}') return json.loads(body) def fetch_text(url): req = urllib.request.Request(url, headers={"User-Agent":"Mozilla/5.0", "Accept":"text/html"}) with urllib.request.urlopen(req, timeout=25) as r: return r.read().decode('utf-8', 'ignore') def won(v): if v in (None, ''): return '-' try: return f"{int(float(v)):,}원" except Exception: return str(v) def resolve_region(region): if not region: return None url = 'https://www.daangn.com/kr/api/v1/regions/keyword?keyword=' + urllib.parse.quote(region) data = fetch_json(url) locs = data.get('locations') or [] if not locs: raise SystemExit(f'지역 후보 없음: {region}') # Exact dong/name match first, then Seoul depth-3, then first candidate. exact = [x for x in locs if region in (x.get('name'), x.get('name1'), x.get('name2'), x.get('name3'))] seoul = [x for x in locs if x.get('name1') == '서울특별시' and x.get('depth') == 3] sel = (exact or seoul or locs)[0] return sel def region_param(sel): return urllib.parse.quote(f"{sel['name']}-{sel['id']}") def absolute(href): if not href: return '' if href.startswith('http'): return href return 'https://www.daangn.com' + href def print_json(obj): print(json.dumps(obj, ensure_ascii=False, indent=2)) def parse_html_detail(url): html = fetch_text(url) title = re.search(r'<title>(.*?)</title>', html, re.S) meta = {} for m in re.finditer(r'<meta[^>]+(?:property|name)=["\']([^"\']+)["\'][^>]+content=["\']([^"\']*)["\']', html): key, value = m.group(1), unescape(m.group(2)).strip() if key in ('description', 'og:title', 'og:description', 'og:image'): meta[key] = value json_ld = [] for m in re.finditer(r'<script[^>]*type=["\']application/ld\+json["\'][^>]*>(.*?)</script>', html, re.S): try: json_ld.append(json.loads(unescape(m.group(1)))) except Exception: pass return { 'source': url, 'title': unescape(title.group(1)).strip() if title else meta.get('og:title'), 'meta': meta, 'json_ld': json_ld[:3], } def cmd_search(args): sel=resolve_region(args.region) if args.region else None params=[] if sel: params.append(('in', f"{sel['name']}-{sel['id']}")) if args.keyword: params.append(('search', args.keyword)) params.append(('_data','routes/kr.jobs._index')) url='https://www.daangn.com/kr/jobs/?'+urllib.parse.urlencode(params) data=fetch_json(url); arr=((data.get('jobsAllPage') or {}).get('jobPosts') or [])[:args.limit] items=[{'title':a.get('title'),'company':a.get('workplaceCompanyName'),'region':a.get('workplaceRegion'), 'address':a.get('workplaceRoadNameAddress'),'salary':a.get('salary'),'salaryType':a.get('salaryType'), 'workDays':a.get('workDays'),'workTimeStart':a.get('workTimeStart'),'workTimeEnd':a.get('workTimeEnd'), 'closed':a.get('closed'),'url':absolute(a.get('href') or a.get('jobsWebDetailUrl'))} for a in arr] print_json({'source':url,'effective_region':data.get('searchRegion') or sel,'count':len(items),'items':items}) def cmd_detail(args): u=args.url.rstrip('/')+'/?_data=routes%2Fkr.jobs.%24job_post_id' try: data=fetch_json(u) print_json({'source':u,'jobPost':data.get('jobPost') or data}) except Exception: detail = parse_html_detail(args.url) detail['data_source_attempted'] = u print_json(detail) p=argparse.ArgumentParser(description='Daangn jobs read-only search/detail') sub=p.add_subpars