Skip to content

feat: Instagram Fashion Decode 자동 수집 어댑터 #259

@cocoyoon

Description

@cocoyoon

Summary

#258 에서 정의한 SourceAdapter 인터페이스의 Instagram 구현체. Instagram 유저/해시태그에서 fashion-decode 포맷(좌: 인물 착장 / 우: 아이템 그리드) 이미지를 수집해 공용 R2 버킷(decoded-media) 및 warehouse.source_media 테이블에 적재한다.

파싱·seed 투입은 #258 의 공용 파이프라인이 담당 — 이 이슈는 Instagram 수집만.

Related:


수집 타겟

Source type 예시 비고
user @bpinkstyles, @outfitsbreakdown fashion-decode 전문 계정
hashtag #fashiondecode, #outfitbreakdown, #celebstyle
search 키워드 검색 v2 (선택)
  • v1: 피드 이미지만 (릴스/Story 제외)
  • platform='instagram', external_id=shortcode (예: C1a2B3c4D5e)

기술적 고려

Instagram 안티봇은 Pinterest보다 강력 — 옵션 비교:

옵션 장점 단점
Graph API (공식) 안정적, 합법 비즈니스 계정만, 본인 컨텐츠만 읽기 가능 (유저 피드 ❌)
Hyperbrowser / Browserbase JS 렌더링, 세션 관리 비용, 로그인 세션 관리 필요
Instaloader + 프록시 오픈소스, 무료 계정 차단 리스크, rate-limit

Hyperbrowser 권장 (#214 Pinterest 와 동일 스택 재사용). 필요 시 쿠키 세션 로테이션.


Phase 1: 어댑터 구현

새 파일

파일 역할
packages/ai-server/src/services/media/adapters/instagram.py InstagramAdapter(SourceAdapter)
packages/ai-server/src/services/media/adapters/_instagram_client.py Hyperbrowser 기반 Instagram 크롤러 (내부)

시그니처

class InstagramAdapter:
    platform: str = 'instagram'

    async def fetch(
        self, source: MediaSource, limit: int = 50
    ) -> list[RawMedia]:
        # source.source_type: 'user' | 'hashtag'
        # source.source_identifier: '@username' | '#hashtag'
        ...

platform_metadata 예시

{
  \"shortcode\": \"C1a2B3c4D5e\",
  \"owner_id\": \"1234567890\",
  \"is_video\": false,
  \"like_count\": 15234,
  \"posted_at\": \"2026-04-10T12:34:56Z\"
}

Phase 2: 환경변수

  • INSTAGRAM_SESSION_COOKIE 또는 INSTAGRAM_USERNAME / INSTAGRAM_PASSWORD
  • (Hyperbrowser 재사용 시 별도 env 불필요)

Phase 3: 스케줄링


Phase 4: Rate-limit / 차단 대응

  • 유저당 최대 요청 수 제한
  • 차단 감지 시 media_sources.is_active=false 자동 비활성화 + 알림
  • 에러 핸들링: 429/401/차단 페이지 감지

검증


Open questions

  • Instagram Graph API 가능성? → 비즈니스 계정 등록 필요, 유저 피드 읽기 불가라 실질 ❌
  • 릴스/Story 썸네일도 수집할지? → v2 로 미루고 v1은 피드만
  • 다중 이미지 포스트(carousel) 처리 → fashion-decode 는 보통 단일 이미지, v1은 첫 이미지만

🤖 Generated with Claude Code


2026-04-29 기준 변경사항 (CIOI 검토)

본문 초안 대비 코드베이스·파이프라인을 기준으로 정리한 진행 방향이다. 구현·PR은 다음 표를 참고하면 된다.

구분 본문 초안 변경·제시 방향
패키지 경로 services/media/adapters/instagram.py #258 이후 monorepo 실제는 packages/ai-server/src/services/raw_posts/adapters/ 에서 SourceAdapter / FetchRequest 계약 (Pinterest 어댑터와 동일 레이어).
적재 R2 decoded-media + warehouse.source_media assetspublic.raw_posts 및 기존 raw posts 파이프라인(R2·키 규약은 Pinterest/raw_posts 쪽과 정합).
크롤 스택 Hyperbrowser 권장 (#214 와 동일) instaloader + instaloader -l 로 만든 세션 사용 (INSTAGRAM_SESSION_USERNAME 등으로 세션 파일 로드).
수집 타겟 v1 user + hashtag 표기 우선 user 구현. hashtag 는 후속.
캐러셀·dedup Open questions: v1 은 첫 이미지만 슬라이드별 external_id = shortcode__N , platform_metadata.carousel_index 로 정리한다. 단일 이미지는 팀 규약에 맞춰 __0 또는 단일 shortcode 유지.
검증 여러 항목·E2E 등 Phase 1 어댑터 범위에서는 실 DB 연결 스모크로 한 게시 분량 정도까지로 한정 가능.
Phase 3~4 2시간 스케줄·차단 시 소스 비활성화 등 어댑터 PR과 분리; 후속 작업으로 쪼개기.

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

Status
Todo

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions