
Daangn Jobs Search
- 1.6k installs
- 6.5k repo stars
- Updated July 27, 2026
- nomadamas/k-skill
Daangn Jobs Search is a CLI and API skill that performs keyword and region-based search and detail retrieval of Korean job postings from public Daangn Jobs web surfaces using Remix `_data` routes and HTML metadata.
About
Skill that performs read-only search and detail retrieval of Korean job postings from Daangn Jobs public web surfaces using keyword and region filters. Uses Python standard library to query Remix `_data` JSON routes and public HTML metadata, with region ID resolution via Daangn's region API. Excludes login, chat, favorites, offers, applications, and any state-changing operations. Falls back to HTML meta when `_data` routes return empty or unavailable.
- Read-only search by keyword and region with automatic region ID resolution
- Fallback from Remix `_data` routes to public HTML meta for detail retrieval
- Python standard library only; no external packages or proxy required
- Search and retrieve Korean job postings from Daangn Jobs by keyword and region without authentication.
- Search and retrieve Korean job postings from Daangn Jobs by keyword and region without authentication.
Daangn Jobs Search by the numbers
- 1,613 all-time installs (skills.sh)
- +128 installs in the week ending Jul 28, 2026 (Skillselion tracking)
- Ranked #331 of 3,301 Productivity & Planning skills by installs in the Skillselion catalog
- Security screen: MEDIUM risk (skills.sh audit)
- Data as of Jul 28, 2026 (Skillselion catalog sync)
daangn-jobs-search capabilities & compatibility
- Capabilities
- search by keyword · filter by region · detail retrieval · region id resolution · fallback to html meta
- Use cases
- web search · data analysis · research
What daangn-jobs-search says it does
당근알바 공개 Remix `_data` JSON route로 채용/알바 공고 목록과 상세 정보를 읽기 전용으로 조회한다.
The helper first tries the legacy `_data` route and falls back to HTML meta when that route returns an empty response.
응답에는 항상 `effective_region` 또는 실제 적용된 지역명을 포함한다.
npx skills add https://github.com/nomadamas/k-skill --skill daangn-jobs-searchAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1.6k |
|---|---|
| repo stars | ★ 6.5k |
| Security audit | 2 / 3 scanners passed |
| Last updated | July 27, 2026 |
| Repository | nomadamas/k-skill ↗ |
What it does
Search and retrieve Korean job postings from Daangn Jobs by keyword and region without authentication.
Who is it for?
Developers and software engineers who need to programmatically discover Korean job postings by location and title without building custom web scrapers.
Skip if: Applications requiring login, messaging, saved jobs, job applications, or any state-changing operations on user accounts.
When should I use this skill?
User requests job search by keyword and region, or asks to view details of a specific job posting URL from Daangn Jobs.
What you get
User receives structured job posting data with titles, salary, work hours, address, and source URL, with region automatically resolved.
- Structured job posting list with title, company, region, address, salary, work hours, and source URL
- Detail view with jobPost JSON-LD or public page metadata
- Effective region applied in every result
By the numbers
- Supports search result limit parameter (default/example: 5)
- Region resolver via Daangn API with priority-ranked candidate selection
- Fallback sequence: Remix `_data` route, then public HTML meta/JSON-LD
Files
Daangn Jobs Search
What this skill does
당근알바 공개 Remix _data JSON route로 채용/알바 공고 목록과 상세 정보를 읽기 전용으로 조회한다.
최종 사용자는 자연어로 요청해도 되고, 필요하면 아래의 Python helper를 직접 실행한다. 외부 패키지나 k-skill-proxy 없이 Python 표준 라이브러리만 사용한다.
When to use
- "당근알바 합정동 카페 찾아봐"
- "홍대 근처 주말 알바 검색"
- "이 당근알바 공고 상세 봐줘"
When not to use
- 당근 계정 로그인이 필요한 작업
- 채팅, 찜, 거래 제안, 문의, 지원, 예약, 계약, 구매처럼 상대방 또는 계정에 영향을 주는 작업
- CAPTCHA/봇 차단/로그인벽 우회가 필요한 작업
Prerequisites
- 인터넷 연결
- Python 3.9+
- 이 저장소 루트에서 실행하거나, 스크립트 경로를 절대경로로 지정
Data surfaces
- Region resolver:
https://www.daangn.com/kr/api/v1/regions/keyword?keyword=<지역명> - Search
_data:/kr/jobs/?in=<지역명>-<id>&search=<keyword>&_data=routes/kr.jobs._index - Detail fallback:
<job-url>redirects tojobs.daangn.com/job-posts/<id>and exposes public HTML title/meta/JSON-LD. The helper first tries the legacy_dataroute and falls back to HTML meta when that route returns an empty response.
Workflow
1. 사용자 요청에서 키워드, 지역명, 가격/거래 유형 같은 필터를 추출한다. 2. 지역명이 있으면 region resolver로 내부 region id를 찾는다. 3. 목록 검색은 category별 _data route를 호출한다. 4. 상세 URL이 주어지면 category별 detail route 또는 공개 HTML 메타를 조회한다. 5. 결과를 짧게 정리하되 source URL과 적용 지역을 보존한다.
Commands
python3 daangn-jobs-search/scripts/daangn_jobs.py search "카페" --region "합정동" --limit 5
python3 daangn-jobs-search/scripts/daangn_jobs.py detail "https://www.daangn.com/kr/jobs/.../"Output fields
- title, company, region, address, salary, salaryType, workDays, workTimeStart, workTimeEnd, closed, url
- detail:
jobPost원문 if the_dataroute is available; otherwise public pagetitle,meta, andjson_ld
Region handling
지역 필터가 있으면 먼저 당근 지역 검색 API로 내부 지역 id를 해석한다.
https://www.daangn.com/kr/api/v1/regions/keyword?keyword=합정동
→ 서울특별시 마포구 합정동, id=231
→ in=합정동-231동일한 지명이 여러 지역에 있으면 다음 우선순위로 선택한다.
1. 사용자가 입력한 문자열이 name, name1, name2, name3 중 하나와 정확히 맞는 후보 2. 서울 depth=3 동 단위 후보 3. 첫 번째 후보
응답에는 항상 effective_region 또는 실제 적용된 지역명을 포함한다. 사용자의 의도와 다른 지역으로 보이면 결과를 단정하지 말고 후보 확인을 요청한다. IP/쿠키 기본 위치에 의존하지 않는다.
Safety and scope
- 읽기 전용 검색/상세 조회만 수행한다.
- 로그인, 채팅, 찜, 거래 제안, 지원, 문의, 예약, 계약, 구매 자동화는 하지 않는다.
- 공개 웹 표면이 바뀌거나 빈 응답/봇 차단/로그인벽이 나오면 실패 모드로 보고하고 우회하지 않는다.
- 결과는 실시간 재고/공고 상태와 달라질 수 있으므로 source URL을 함께 제시한다.
Failure modes
- 당근의 Remix route 이름이나 JSON shape가 변경되면
_data조회가 실패할 수 있다. - 지역명이 넓거나 중복되면 다른 행정동이 선택될 수 있다.
- 검색 결과가 0건이어도 사이트 정책/지역 기본값/필터 조합 때문일 수 있으므로 source URL을 보존한다.
- 상세 조회는 삭제/종료/비공개 전환된 글에서 실패할 수 있다.
Done when
- 지역명이 있으면 지역 id를 해석하고 적용했다.
- 목록 조회 또는 상세 조회를 최소 1회 수행했다.
- 결과에 source URL과 effective region을 포함했다.
- 인증/거래성 액션은 수행하지 않았다.
#!/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_subparsers(dest='cmd', required=True)
s=sub.add_parser('search'); s.add_argument('keyword', nargs='?'); s.add_argument('--region'); s.add_argument('--limit',type=int,default=10); s.set_defaults(func=cmd_search)
d=sub.add_parser('detail'); d.add_argument('url'); d.set_defaults(func=cmd_detail)
args=p.parse_args(); args.func(args)
Related skills
How it compares
Choose daangn-jobs-search over generic web scrapers when you need Daangn-specific region ID resolution and Remix _data route handling for Korean 알바 listings.
FAQ
Does this skill log in to Daangn or apply for jobs automatically?
No. This skill performs read-only search and detail retrieval only. Login, chat, applications, offers, and any account-affecting actions are explicitly excluded.
What happens if a job posting is deleted or the region name is ambiguous?
If a posting is deleted, detail retrieval fails cleanly. For ambiguous regions, the skill applies priority: exact name match, then Seoul ward-level (depth=3) candidates, then first match. Results always include the effective region applied so you can verify.
What if Daangn's website structure changes?
If Remix `_data` routes change or return empty, the skill reports failure instead of attempting to bypass auth walls or scrape with fragile HTML parsing. Source URL is always preserved so you can check the live site.
Is Daangn Jobs Search safe to install?
skills.sh reports 2 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.