기록된 세션에서 API 클라이언트 도출하기
브라우저를 구동하는 것은 첫 번째 방문에는 적합한 도구이지만, 100번째 방문에는 잘못된 도구입니다. 이 스킬은 사이트를 사용하는 동안 한 번 네트워크 트래픽을 기록하고, 캡처된 요청을 사이트의 내부 API와 직접 통신하는 독립형 클라이언트(스크립트, CLI, 라이브러리)로 변환합니다.
기록 자체에는 필요한 모든 것이 포함됩니다: agent-browser는 기본적으로 텍스트 응답 본문(JSON/HTML/JS)을 HAR에 포함하므로, 브라우저를 닫은 후에도 오프라인에서 엔드포인트 형태를 연구할 수 있습니다.
워크플로
1. 기록 HAR 캡처를 시작하고, 클라이언트에 포함할 흐름을 브라우저에서 실행
2. 식별 노이즈 속에서 실제 API 엔드포인트 찾기
3. 추출 요청 형태, 응답 스키마, 인증 정보 추출
4. 생성 흐름당 하나의 함수로 클라이언트 작성
5. 검증 완료 선언 전에 모든 엔드포인트를 실제로 호출하여 확인
1. 기록
agent-browser network har start # 기본적으로 텍스트 응답 본문 포함
# ... 사이트 탐색: 검색, 상세 페이지 열기, 페이지네이션 등 ...
agent-browser network har stop /tmp/site.har
- 클라이언트가 지원해야 하는 모든 흐름을 실행하고, 각 흐름을 서로 다른 입력(두 개의 검색어, 두 개의 상세 페이지)으로 최소 두 번 이상 실행하세요. 기록된 URL을 비교(diff)하면 어떤 부분이 파라미터인지 알 수 있습니다.
- 사이트에 로그인이 필요한 경우, 자격 증명이 불필요하게 기록에 남지 않도록 HAR를 시작하기 전에 로그인하세요. 세션 쿠키는 3단계에서 별도로 내보냅니다.
--content all은 바이너리 본문도 포함합니다(base64).--content none은 포함을 비활성화합니다. 본문당 최대 크기는 2MB입니다.
세션이 열려 있는 동안 agent-browser network requests 및 network request <id> 명령어로도 동일한 데이터를 대화식으로 확인할 수 있습니다. 하지만 HAR만이 브라우저 탐색과 종료를 견디므로, 여러 페이지에 걸친 작업에는 HAR을 선호하세요.
2. 엔드포인트 식별
jq로 HAR을 조회합니다:
# 모든 JSON API 호출: 메서드, URL, 상태
jq -r '.log.entries[]
| select(.response.content.mimeType | test("json"))
| "\(.request.method) \(.response.status) \(.request.url)"' /tmp/site.har
분석 및 인프라 노이즈는 무시하세요: 텔레메트리 엔드포인트(/collect, /track, /beacon, /log), 서드파티 도메인(google-analytics, segment, sentry, datadog, intercom, hotjar), 정적 자산. 실제 API는 일반적으로 자사(first-party) JSON이며, 사용자가 수행한 작업과 상관관계가 있습니다.
3. 형태 및 인증 추출
# 하나의 엔드포인트에 대한 전체 세부 정보: 요청 헤더, POST 본문, 응답 본문
jq '.log.entries[] | select(.request.url | test("api/search"))
| {request: {method: .request.method, headers: .request.headers,
postData: .request.postData.text},
response: .response.content.text}' /tmp/site.har
- 응답 스키마:
.response.content.text를 읽으세요. 실제 페이로드이며, 이를 사용하여 타입을 도출합니다. - 인증: 엔드포인트 간 요청 헤더를 비교하세요.
authorization,cookie,x-csrf-token,x-api-key, 사이트별x-*헤더를 찾으세요. 중요한 것만 재생(playback)하세요. 5단계에서 생략하여 테스트합니다. - 쿠키:
agent-browser cookies get --json > cookies.json으로 라이브 세션을 내보내 클라이언트가 런타임에 로드할 수 있게 하세요. 생성된 소스 코드에 쿠키 값을 하드코딩하지 마세요.
4. 클라이언트 생성
- 기록된 각 흐름당 하나의 함수(
search(query),getItem(id))를, 관찰된 응답 본문에서 타입을 유추하여 생성합니다. - 인증 자료(쿠키, Bearer 토큰)는 파일이나 환경 변수에서 로드하며, 만료 시 브라우저 로그인을 다시 실행하라는 명확한 오류 메시지를 표시합니다.
- API가 실제로 요구하는 헤더를 재현하세요. 일부 사이트는 일치하는
user-agent,referer,x-requested-with가 없으면 403 오류를 반환합니다. - 기록된 쿼리 문자열에 나타난 페이지네이션, 정렬, 필터 파라미터를 함수 옵션으로 유지하세요.
5. 검증
생성된 모든 함수를 라이브 API에 대해 호출하고 응답 형태를 기록과 비교하세요. 일반적인 실패:
| 증상 | 원인 | 해결책 |
|---|---|---|
| 401/403 | 세션 만료 또는 누락 | agent-browser로 재로그인하고 쿠키 다시 내보내기 |
| 403/419 on writes | CSRF 토큰이 세션별 또는 양식별임 | 먼저 토큰 엔드포인트를 가져오거나, 해당 흐름은 브라우저 기반 유지 |
| 작동하다가 중단됨 | 서명되거나 만료되는 요청 파라미터 | 해당 단계는 브라우저로 폴백(fallback), 나머지는 도출 |
| HAR과 다른 형태 | A/B 테스트 또는 지리 종속적 응답 | 다시 기록하고 합집합을 선택적 필드로 처리 |
주의사항
- 내부 API는 버전이 없고 통지 없이 변경됩니다. HAR을 보관하여 클라이언트를 다시 도출할 수 있도록 하세요.
- 사이트의 이용약관과 속도 제한을 준수하고, 대량 가져오기 시 지연을 추가하세요.
- HAR 파일에는 라이브 세션 자격 증명(쿠키, 토큰, POST 본문)이 포함되어 있습니다. 이를 비밀처럼 취급하여 버전 관리에 포함하지 말고, 작업이 끝나면 삭제하세요.