Instagram 데이터 ZIP 구조: followers와 following을 실제 파일로 해부하기
613MB Instagram 내보내기 ZIP과 테스트 파일을 직접 파싱해 관계 JSON의 경로, 래퍼 차이, 식별자, timestamp 관측기간과 정확도 한계를 설명합니다.
CheckMate 운영자 · 최초 발행 · 사실 검토 · 약 14분
Instagram ZIP은 “팔로워 목록 두 개를 빼면 끝”인 단순한 파일이 아닙니다. 같은 관계 정보도 내보내기 버전과 언어에 따라 최상위 배열, relationships_followers 래퍼, relationships_following 래퍼, label_values 형식으로 달라질 수 있습니다. 파일 이름 하나와 특정 키 하나만 가정하면 일부 계정에서 0명으로 나오거나 첫 파일만 읽는 문제가 생깁니다.
CheckMate 운영자가 제공받은 613MB 실제 ZIP을 로컬에서 분석했을 때 followers 기록의 timestamp 범위는 2,794일, following은 2,783일이었습니다. 따라서 “followers는 언제나 약 365일만 제공된다”는 보편 규칙은 이 파일과 맞지 않습니다. 현재 버전은 각 목록의 최소·최대 timestamp 차이를 관측값으로 표시하고, 기간 차이만으로 누락을 단정하지 않습니다.
이 글은 파일 안에 실제로 있는 값과 그 값으로 알 수 없는 것을 분리합니다. username·프로필 URL·timestamp·일부 신형 파일의 fbid는 관찰할 수 있지만, 모든 내보내기에 영구 고유 ID가 있다고 가정할 수는 없습니다. 그래서 현재 비맞팔 계산, 닉네임 변경 가능성, 실제 과거 언팔 사건은 서로 다른 신뢰도로 다뤄야 합니다.

1. 관계 파일은 어디에 있고 왜 이름이 달라지는가
한국어 내보내기에서는 connections/followers_and_following 또는 이에 대응하는 번역 경로 아래에서 관계 파일을 자주 찾습니다. 그러나 Meta가 폴더명을 바꾸거나 전체 정보 선택 여부에 따라 더 깊은 경로에 둘 수 있어, CheckMate는 ZIP 엔트리의 끝 경로와 알려진 후보를 함께 검사합니다. followers_1.json만 찾고 종료하지 않고 번호가 붙은 모든 followers 파일을 합칩니다.
관계 파일 두 개는 모양도 다를 수 있습니다. followers 파일은 배열이 바로 시작하는 구형 사례가 있고, following 파일은 relationships_following이라는 객체 키 아래 배열이 들어가는 사례가 있습니다. 신형 export 일부는 label_values와 fbid를 사용합니다. “둘 다 같은 타입으로 캐스팅”하는 코드는 한쪽을 놓치기 쉽습니다.
| 대상 | 관찰한 대표 형태 | 파서가 해야 할 일 |
|---|---|---|
| followers_N.json | 최상위 배열 또는 relationships_followers | 번호 파일을 모두 모으고 래퍼를 해제 |
| following.json | relationships_following 객체 | 래퍼 안의 배열을 읽기 |
| 신형 관계 항목 | label_values + 선택적 fbid | 표시 이름과 username을 분리하고 fbid가 있을 때 우선 |
| 알 수 없는 래퍼 | 첫 비어 있지 않은 배열 | 모르는 필드는 무시하되 섹션 오류를 기록 |
connections/
└── followers_and_following/
├── followers_1.json
├── followers_2.json # 계정에 따라 존재
└── following.json2. 한 사람 항목에서 실제로 읽는 필드
구형 string_list_data 항목에는 title, value, href, timestamp가 함께 있거나 일부만 있습니다. title과 value가 과거 이름이고 href에서 뽑은 username이 현재 이름처럼 보이는 사례도 있지만, 그 사실만으로 닉네임 변경을 확정할 수는 없습니다. 데이터 생성 시점과 필드 갱신 방식이 공개 계약으로 보장되지 않기 때문입니다.
신형 일부 항목의 fbid는 숫자 문자열 형태의 계정 식별자로 관찰됐습니다. 두 목록 모두 같은 fbid를 제공하면 username이 달라도 관계를 연결하는 가장 강한 키로 사용할 수 있습니다. 다만 구형 파일에는 없으므로 전체 서비스 설명을 “고유 ID로 100% 추적”이라고 바꾸면 안 됩니다. displayName은 동명이인이 가능해 관계 매칭 키로 사용하지 않습니다.
| 필드 | 쓸 수 있는 범위 | 주의할 점 |
|---|---|---|
| fbid | 양쪽 파일에 있을 때 우선 관계 매칭 | 모든 export에 존재하지 않음 |
| href username | 프로필 경로에서 표시 username 추출 | 경로가 영구 ID라는 보장은 없음 |
| title / value | 구형 형식의 보조 username 후보 | 서로 달라도 닉변 확정은 아님 |
| timestamp | 목록 내부 관측기간과 일부 이벤트 시점 | 계정 생성일이나 완전한 이력 기간이 아님 |
| displayName | 화면 표시 | 동명이인 때문에 매칭 키로 사용 금지 |
{
"title": "sample_old_name",
"string_list_data": [{
"href": "https://www.instagram.com/_u/sample_name",
"value": "sample_name",
"timestamp": 1700000000
}]
}3. 2,794일은 “전체 데이터 보장”도 “365일 제한”도 아니다
관측기간은 유효한 timestamp 중 가장 늦은 값에서 가장 이른 값을 빼 86,400초로 나눈 정수 일수입니다. 실제 ZIP에서 followers 2,794일, following 2,783일이 나왔다는 것은 그 사이의 기록이 파일에 존재한다는 뜻입니다. 모든 날짜가 빠짐없이 포함됐거나 그 기간의 모든 과거 팔로워가 들어 있다는 뜻은 아닙니다.
이전 버전은 following이 400일 이상이고 followers가 400일 미만이면 잘린 것으로 보는 휴리스틱과, followers 수가 following의 30%보다 작으면 의심하는 비율 규칙을 사용했습니다. 실제 관계 비율은 계정 성격마다 다르고, 제공 ZIP은 365일 가정을 반박했습니다. Recovery Release에서는 두 규칙을 제거했습니다.
현재 partial 판정은 별도 audience insight에서 실제 팔로워 수를 읽을 수 있을 때만 사용합니다. 파일의 followers 항목 수가 그 실제 수보다 10% 이상 적을 때 재다운로드 안내를 보여줍니다. 정확히 10%인 경계도 테스트합니다. 실제 수가 없으면 span이나 팔로잉 비율만으로 “전체 기간이 아니다”라고 단정하지 않습니다.
| 화면 값 | 계산 방법 | 말할 수 있는 것 | 말할 수 없는 것 |
|---|---|---|---|
| followers 2,794일 | followers timestamp 최대-최소 | 파일 안 관측 시각 범위 | 그 기간 전체 팔로워가 완전함 |
| following 2,783일 | following timestamp 최대-최소 | 파일 안 관측 시각 범위 | 팔로잉 전체 이력 보장 |
| 누락 N명 | 실제 팔로워 수-파일 항목 수 | 10% 이상 차이의 정량 경고 | 누가 누락됐는지 확정 |
4. 맞팔·현재 비맞팔 계산은 집합 비교지만 식별자가 핵심이다
기본 관계는 following에 있고 followers에는 없는 계정을 “현재 나를 팔로우하지 않는 계정”으로 분류합니다. 반대로 followers에만 있으면 “내 팬”, 양쪽에 있으면 맞팔입니다. 이 계산은 내보내기 생성 시점의 스냅샷을 비교하므로 “어제 누가 나를 언팔했다”는 사건 이력을 알려주지 않습니다. 실제 변화는 서로 다른 두 스냅샷을 비교해야 합니다.
동일성 매칭은 fbid가 있으면 fbid를 우선하고, 없으면 href에서 추출한 username·title·value 후보를 소문자로 정규화해 비교합니다. 한 항목 내부의 식별자가 어긋나면 결과 배지에 “닉네임 변경 가능성”이라고 표시할 수 있지만, 비활성화·탈퇴·재가입까지 구분하지는 못합니다.
- 현재 비맞팔: following에는 있고 followers에는 없는 식별자
- 내 팬: followers에는 있고 following에는 없는 식별자
- 맞팔: 양쪽에서 동일 fbid 또는 호환되는 username 식별자를 찾은 항목
- 실제 언팔 변화: 날짜가 다른 두 ZIP을 snapshot compare로 비교한 결과
5. 파서에서 반드시 처리해야 할 엣지 케이스
JSON 파서는 정상 파일만 처리하는 것보다 실패를 섹션 단위로 격리하는 것이 중요합니다. 광고 정보 형식이 바뀌어도 관계 결과가 사라지면 안 되고, unknown 필드 하나 때문에 ZIP 전체를 실패시켜서도 안 됩니다. CheckMate는 각 인사이트 파싱 오류를 기록하고 나머지 결과를 계속 표시합니다.
한글 label이 잘못된 latin1처럼 보이는 이중 인코딩 사례도 있습니다. 유효한 UTF-8 바이트열일 때만 재해석하고, 이미 정상 유니코드이거나 디코딩에 실패하면 원문을 유지합니다. timestamp는 초·밀리초·마이크로초가 섞일 수 있어 크기에 따라 초 단위로 정규화합니다.
- followers_N 분할 파일을 숫자 순서와 무관하게 모두 합치고 중복을 정규화한다.
- 빈 media 배열보다 뒤에 있는 실제 label_values 배열을 먼저 찾는다.
- timestamp 0, 음수, NaN은 관측기간에서 제외한다.
- 표시 이름은 동명이인 오매칭 위험 때문에 관계 키로 쓰지 않는다.
- 모르는 섹션은 null로 낮추고 관계 분석까지 함께 실패시키지 않는다.
확인한 출처와 검증 방법
- Meta Newsroom — Download Your Information의 Accounts Center 통합 — 내보내기 기능의 공식 위치를 확인했습니다.
- Instagram Help Center — 정보 사본 내보내기 — 내보내기 기능 자체의 공식 기준입니다. 파일 스키마는 실제 ZIP 관찰로 별도 검증했습니다.
- CheckMate 이용약관 — 결과 정확도와 한계 — 현재 비맞팔, 식별자 불일치, 파일 시점 한계를 공개합니다.
자주 묻는 질문
followers가 following보다 기간이 짧으면 파일이 잘린 건가요?
그 차이만으로는 알 수 없습니다. 두 목록은 서로 다른 이벤트 집합이며 timestamp의 최소·최대도 다를 수 있습니다. 별도 실제 팔로워 수와 10% 이상 차이가 확인될 때만 누락 경고를 표시합니다.
profile URL의 /_u/username은 영구 고유 ID인가요?
아닙니다. 현재 파서는 경로에서 username을 추출하는 호환 형식으로만 사용합니다. 영구 불변 식별자라고 가정하지 않으며, fbid가 양쪽에 있을 때 그 값을 우선합니다.
한 번의 ZIP으로 누가 최근 언팔했는지 알 수 있나요?
알 수 없습니다. 한 ZIP은 생성 시점의 현재 관계를 보여줍니다. 실제 변화는 날짜가 다른 두 스냅샷을 같은 규칙으로 비교해야 합니다.
followers_2.json도 꼭 필요한가요?
있다면 반드시 함께 읽어야 합니다. 첫 파일만 사용하면 팔로워 수와 관계 계산이 실제 파일보다 작아집니다.