--- name: daangn-wide-search description: 당근마켓 웹에서 넓은 지역을 훑어 매물을 찾을 때 사용. 당근 웹 검색은 "동 하나"로만 되기 때문에 구·시·전국 단위로 찾으려면 지역코드를 순회해야 한다. 대형가전·노트북처럼 매물이 드물어 한 동네에서는 안 나오는 물건을 찾을 때. --- # 당근마켓 광역 검색 당근 웹(`www.daangn.com`)의 중고거래 검색은 **선택된 행정동 하나**의 매물만 보여준다. "전국 검색" 기능이 없다. 넓게 찾으려면 지역코드를 바꿔가며 순회해야 한다. ## URL 구조 ``` https://www.daangn.com/kr/buy-sell/?in=x-<지역ID>&search=<검색어>&only_on_sale=true ``` - `in` 파라미터의 **이름 부분은 무시되고 숫자 ID만 유효하다.** `x-448`처럼 아무 이름이나 써도 된다 - `only_on_sale=true` 를 붙이면 거래완료 매물이 빠진다. 안 붙이면 결과 대부분이 이미 팔린 것 - 응답은 서버사이드 렌더링이라 fetch만으로 매물이 다 들어온다 (브라우저 불필요) ## 지역 ID 지도 (2026-08 실측) 시도 순서로 연속 배치돼 있다. 서울은 구 단위로 아래와 같다. | 구 | ID | 구 | ID | |---|---|---|---| | 종로 | 3~19 | 양천 | 239~260 | | 중구 | 20~35 | 강서 | 261~280 | | 용산 | 36~52 | 구로 | 281~296 | | 성동 | 53~70 | 금천 | 297~306 | | 광진 | 71~86 | 영등포 | 307~325 | | 동대문 | 87~110 | 동작 | 326~340 | | 중랑 | 111~127 | 관악 | 341~361 | | 성북 | 128~144 | 서초 | 362~380 | | 강북 | 145~157 | 강남 | 381~403 | | 도봉 | 158~172 | 송파 | 404~431 | | 노원 | 173~185 | 강동 | 432~450 | | 은평 | 186~206 | | | | 서대문 | 207~220 | 마포 | 221~238 | 서울 밖: 부산 451~, 대구 ~680~830, 인천 ~831~960, 광주 ~961~, 대전 ~1051~, 울산 ~1151~, 세종·경기 ~1251~1800, 강원 ~1900, 충북 ~2100, 충남 ~2400, 전북 ~2700, 전남 ~3000. **경계는 정확하지 않다.** 확인이 필요하면 아래로 지역명을 읽어 검증한다. ```js const m = html.match(/data-gtm="search_filter">([^<]+)]*href="(\/kr\/buy-sell\/[^"]+)"[\s\S]*?<\/a>/g; const res=[]; let m; while((m=re.exec(html))){ const seg=m[0]; const txt=seg.replace(/]*>/g,'').replace(//g,'') .replace(/<[^>]+>/g,'\u0001').split('\u0001').map(s=>s.trim()).filter(Boolean); res.push({href:'https://www.daangn.com'+m[1], t:txt.join(' | ')}); // "제목 | 가격 | 동네 | 시간" } return res; } ``` 상세 페이지는 fetch 후 `매너온도` 다음 20줄 정도를 읽으면 본문·채팅수·관심수가 나온다. ## 속도와 차단 CloudFront가 앞단에 있어 **너무 빠르면 403**이 뜬다. 한 번 막히면 1~2분 쉬어야 풀린다. - 안전 구간: **2~3개 병렬 + 250~450ms 간격** (초당 약 2.5~5건). 이 속도로 900개 동을 돌았고 차단 0회 - 위험 구간: 10병렬 연속. 약 120건에서 막혔다 - 403이 연속 8건 넘게 나오면 15~20초 쉬고 재개하는 가드를 넣는다 - `page.goto()`(브라우저)는 동당 2.4초로 fetch보다 3~4배 느리다. **fetch를 쓴다** - REPL 툴콜은 120초에서 끊긴다. 한 콜에 250~300개 동이 한계이니 나눠 돌린다 - 에이전트 탭이 중간에 닫혀 `page`가 null이 되는 일이 있다. fetch 방식이면 영향 없다 ## 검색어 전략 당근 검색은 토큰 기반이라 **한 단어로는 다 못 잡는다.** 2~3개를 돌린다. - 예: 세탁건조기 → `콤보`(워시콤보·AI콤보 잡힘) + `세탁건조기` + `워시타워` - `콤보` 같은 일반어는 영화 팝콘 쿠폰 같은 노이즈가 압도적이다. 수집 후 `/세탁|건조/` 등으로 거른다 - 결과는 `Map`(href → 제목)에 모아 자동 중복 제거한다. 같은 판매자가 여러 동네에 중복 게시하는 일이 잦다 ## 결과 정리 제목 문자열에서 가격·세대를 뽑아 정렬하면 시세 분포가 바로 보인다. ```js const price = t => { const m=t.match(/([\d,]+)원/); return m?+m[1].replace(/,/g,''):null; }; ``` ## 주의 - **대형가전은 지방 매물을 넣지 말 것.** 용달비 40~50만원이면 가격 이점이 사라진다. 수도권까지가 실용 범위 - 중고 시세가 신품가에 근접하면 신품·구독과 나란히 비교해서 보고한다. 중고만 훑고 "이게 최저가"라고 하면 반쪽짜리다