How I Sniffed Xiaohongshu's Collection API in 90 Seconds — and Why CORS Made Me Rewrite the Whole Approach
개요
Xiaohongshu(중국의 인스타그램과 핀터레스트 결합 서비스)의 수집 API에서 사용자 저장 게시물 목록을 추출하기 위한 네 가지 접근 방식이 실패 후, 브라우저가 요청을 발행하고 응답을 수신하는 방식으로 250개의 저장된 게시물을 90초 만에 성공적으로 가져오는 해결책이 제시되었습니다.
주요 내용
* 목표: 오프라인 분석을 위해 사용자의 Xiaohongshu 저장 게시물 목록을 추출하는 것.
* 초기 접근 방식 실패:
* 로그인 및 쿠키 폴링: web_session 쿠키가 로그인 없이도 설정될 수 있어 신뢰할 수 없음. 실제 로그인 상태를 확인하기 위해 /me 엔드포인트에서 guest: false 여부를 확인하는 방식으로 수정.
* 직접 API 요청: 수집 API 엔드포인트 추측 실패 (404 응답).
* Playwright 네트워크 스니핑: 올바른 엔드포인트(https://edith.xiaohongshu.com/api/sns/web/v2/note/collect/page) 발견했으나, 직접 요청 시 x-s 서명 헤더 부재로 실패.
* 핵심 문제: Xiaohongshu는 API 요청 시 x-s (서명), x-s-common (플랫폼 지문), x-t (타임스탬프) 헤더를 요구하며, 이는 프론트엔드 JavaScript에서 계산됨. 이를 Python에서 재현하는 것은 복잡하고 유지보수가 어려움.
* 최종 해결책 (브라우저를 통한 요청):
* Playwright를 사용하여 페이지 이동, 특정 탭 클릭, 스크롤 등 사용자 인터랙션을 자동화.
* 프론트엔드 JavaScript가 자체적으로 서명을 생성하고 API 요청을 보내도록 함.
* page.on("response")를 사용하여 API 응답을 수신하고 JSON 본문을 캡처.
* 스크롤이 새로운 요청을 트리거하고, 브라우저가 서명을 처리하며, 리스너가 응답을 수집하는 방식.
* 결과: 250개의 저장된 게시물 데이터를 90초 내에 JSON 형식으로 추출.
* 활용: 추출된 데이터는 LLM/Chat, Image-Gen, Coding-Agent 등 AI 관련 관심사를 분류하는 데 사용되었으며, 이는 iOS 프롬프트 관리자 앱의 기능 개발 결정에 영향을 미침.
* 일반화된 교훈:
* 쿠키는 항상 로그인 상태를 의미하지 않으며, 실제 API 호출로 검증해야 함.
* 여러 엔드포인트 추측이 실패하면 브라우저 스니핑을 활용.
* API 요청 서명 문제는 브라우저에게 서명을 아웃소싱하는 방식으로 해결.
* 고정된 스크롤 횟수 대신 응답 없는 유휴 시간을 감지하는 것이 더 효과적.
시사점
Xiaohongshu와 같이 API 요청에 복잡한 서명 체계를 요구하는 플랫폼에서 데이터를 추출할 때, 직접 API를 호출하기보다 브라우저의 요청 기능을 활용하고 응답을 수신하는 방식이 효율적이고 유지보수하기 용이한 접근법을 제공합니다.
댓글
GitHub Discussions