인스타그램이 주는 "내 정보 내보내기" ZIP을 처음 열어본 사람은 대부분 당황합니다. 폴더가 수십 개, JSON은 비슷비슷한 이름, 그리고 어딘가에서 데이터가 잘려 있습니다. 이 글은 그 ZIP 파일을 실제로 파싱해 CheckMate를 만든 입장에서, 파일별 역할과 누구도 설명하지 않는 365일 절단의 이유까지 기술적으로 풀어냅니다.
작성자: 이명진 (thingineeer) · 업데이트: 2026-04-12 · 읽는 시간: 약 12분
followers_1.json / following.json / followers_unfollowed.json은 무엇이 다른가close_friends.json,pending_follow_requests.json 같은 덜 알려진 파일에는 무엇이 있는가Instagram 앱 → 계정 센터 → 내 정보 및 권한 → 내 정보 내보내기에서 "전체 기간 + JSON"으로 요청하면 수 분에서 최대 48시간 후 ZIP 파일을 받게 됩니다. 파일명은 보통 instagram-유저명-YYYY-MM-DD-해시.zip 형태이고, 해제하면 다음 구조가 나옵니다(발췌 — 체크한 항목에 따라 일부 폴더는 없을 수 있습니다).
맞팔/언팔 확인에 필요한 건 이 중 거의 전부가 아니라 딱 하나의 폴더, connections/followers_and_following/ 뿐입니다. CheckMate도 이 경로만 읽습니다. 나머지는 인사이트 대시보드(좋아요·댓글 상위 인물 등)를 만들 때 선택적으로 사용합니다.
이름이 비슷해서 헷갈리는 세 파일의 역할을 먼저 표로 정리합니다. 실제 ZIP에 존재하는 이름을 기준으로 했으며, 일부 파일명은 파이썬 쪽 분석 툴에서 흔히 쓰는 별명(unfollowed.json 등)과 다를 수 있습니다.
| 파일명 | 의미 | 기간 제한 | CheckMate에서 쓰는가 |
|---|---|---|---|
followers_1.json(+ followers_2, 3 … 팔로워 많을 때) | 나를 팔로우하는 사람 | 약 365일 (뒤에서 상세 설명) | 필수 |
following.json | 내가 팔로우하는 사람 | 전체 | 필수 |
recently_unfollowed_profiles.json | 내가 최근 언팔한 사람 | 최근 몇 달 (비공식) | 보조 (히스토리 분석) |
pending_follow_requests.json | 내가 보낸 팔로우 요청 중 아직 승인 안 된 것 | 현재 상태 스냅샷 | 보조 (인사이트 옵션) |
close_friends.json | 친한 친구 리스트 | 현재 상태 스냅샷 | 선택 |
blocked_profiles.json | 차단한 계정 | 누적 전체 | 선택 |
{
"relationships_followers": [
{
"title": "",
"media_list_data": [],
"string_list_data": [
{
"href": "https://www.instagram.com/_u/some_user",
"value": "some_user",
"timestamp": 1701456789
}
]
},
{ "...다음 팔로워..." }
]
}주의할 포인트 네 가지입니다.
relationships_followers, following은 relationships_following, 언팔 이력은 relationships_unfollowed_users입니다.title은 보통 비어 있고, value가 실제 @handle입니다.https://www.instagram.com/_u/username 형태이며, 브라우저에서 열면 앱으로 딥링크됩니다. CheckMate에서도 이 경로를 그대로 쓰므로 parseHrefUsername이 이 형식을 기준으로 파싱합니다.구조 자체는 매우 유사하지만 최상위 키가 relationships_following이고, 이 파일에는 절단이 없습니다. 즉 몇 년 전 팔로우한 계정도 그대로 들어 있습니다. 비대칭성이 분석 정확도에 직접 영향을 주기 때문에 다음 섹션에서 별도로 다룹니다.
경쟁 도구들이 거의 설명하지 않는 지점입니다. 사용자 입장에서는 "숫자가 안 맞네?" 한 마디지만, ZIP을 직접 파싱해 보면 규칙이 보입니다. Instagram이 데이터 내보내기를 설계한 방식은 다음과 같습니다.
| 데이터 | 주체 | 제공 범위 | 근거(해석) |
|---|---|---|---|
| following | 내가 수행한 팔로우 액션 | 전체 | 내 행동 기록 → 주체가 "나"이므로 GDPR/개인정보 주권 기준 전체 제공 |
| followers | 타인이 나를 팔로우한 액션 | 대략 1년(약 365일) | 타인의 행동 기록 → 제3자 데이터 → 제공 범위가 좁고, 최근성 기준으로만 내보냄 |
"내가 한 팔로우(following)"는 내 데이터라 전체가 주어지지만, "남이 나를 팔로우한 것(followers)"은 상대방의 데이터 성격이 강하므로 최근 활동 기준으로만 반환된다. 그래서 현재 UI에 표시되는 팔로워 수와 ZIP 속 followers 개수가 다른 게 정상입니다.
정확한 365일이라는 숫자는 Instagram의 공식 문서에 명시돼 있지 않고, 시기에 따라 6개월·1년 사이에서 움직이는 것으로 관측됩니다. CheckMate는 보수적으로 "약 1년 이내에 너를 팔로우한 사람만 포함된다"고 안내하며, 그 이전에 팔로우했는데 최근 아무 행동이 없는 계정은 ZIP에서 빠질 수 있다는 점을 전제로 분석합니다.
timestamp 값이 매우 오래됐고 username이 "instagramuser"처럼 일반화된 경우가 그 신호입니다.2025~2026년 데이터 정책 변경 전후의 차이는 별도 글 — Instagram 데이터 정책 변경 해설에서 다룹니다.
혼동이 잦은 포인트라 다른 각도로도 설명합니다. 데이터 내보내기는 "현재 상태"가 아니라 "기간 내 이벤트 로그"에 가깝습니다. following은 내가 일으킨 이벤트라 계정이 살아 있는 한 그대로 남지만, followers는 타인이 나를 대상으로 일으킨 이벤트이고 Instagram이 제3자 행동 이력을 "최근성" 기준으로만 되돌려 줍니다. 그래서 "한 번 맞팔이었지만 최근 1년간 아무 상호작용이 없던 계정"은 팔로우 관계가 유지돼 있어도 ZIP의 followers에서 누락될 수 있습니다.
이 때문에 CheckMate는 세 가지 보정 로직을 운용합니다. (1) timestamp가 오래된 following 항목에 "장기" 태그를 붙여 사용자가 차집합 결과를 무작정 믿지 않도록 안내하고, (2) "맞팔 아님"으로 분류된 결과에는 "상대가 오래된 팔로워일 가능성" 주석을 보여주며, (3) 같은 계정을 한 달 간격으로 두 번 분석했을 때의 차이를 비교해 1년 절단 창이 움직이는 양을 시각화합니다. 이 세 장치가 "ZIP 데이터의 한계"를 UI 레벨에서 보완하는 방식입니다.
맞팔 확인에는 필수가 아니지만, 인사이트 대시보드를 만드는 데 쓸 수 있는 파일들입니다.
친한 친구 기능에 추가된 계정 리스트입니다. 일방적 선택이므로 상대는 모릅니다. 구조는 followers와 동일 — relationships_close_friends 배열 안에 string_list_data 가 있습니다.
비공개 계정에 팔로우를 보냈는데 승인 대기 중인 목록. "왜 내가 팔로잉은 많은데 상대는 반응이 없는가?" 같은 질문에 답이 됩니다. 오래된 pending이 쌓이면 팔로우 요청 도달률이 떨어지니 정리 대상 후보입니다.
내가 최근 언팔한 계정 리스트입니다. "팔로우 해제 이력"이 앱에는 UI로 노출되지 않기 때문에 ZIP만이 유일한 공식 기록입니다. 보통 3~6개월치가 남습니다.
차단/제한한 계정. 이 둘은 followers/following 로직에 영향을 줍니다. 차단한 계정은 followers에서 자동으로 빠지므로, "분명히 맞팔이었는데 사라졌다"면 내가 그 사람을 차단했을 가능성도 확인해 볼 수 있습니다.
Instagram은 내보내기 요청 시 HTML 또는 JSON 형식을 선택할 수 있습니다. 처음 쓰는 사람이 자주 하는 실수가 HTML을 그대로 두는 것인데, 분석 용도로는 거의 쓸 수 없습니다.
| 특성 | HTML 형식 | JSON 형식 |
|---|---|---|
| 목적 | 사람이 브라우저로 눈으로 보기 | 기계 파싱·분석 |
| 구조화 정도 | <a href> 태그 + 텍스트만 | 스키마 있는 배열/객체 |
| timestamp 보존 | 부분적 (텍스트로만) | 완전 (Unix epoch) |
| 파일 크기 | 큰 편 (스타일 포함) | 작음 |
| CheckMate 지원 | 비권장 — 정확도 낮음 | 권장 |
HTML을 받았다면 다시 내보내기 요청을 JSON으로 걸어 주세요. 과거 ZIP과 새 ZIP 간 기간 설정이 같다면 결과는 거의 동일합니다. 자세한 재요청 절차는 Instagram 데이터 다운로드 방법 가이드에서 다룹니다.
"도구를 쓰지 않고 직접 언팔을 뽑을 수 있을까?" — 네, 가능합니다. 다음 코드는 followers와 following의 차집합을 계산하는 최소 예제입니다. CheckMate 내부 로직도 본질은 이와 같고, 다중 followers_N.json 병합, 타임존 처리, 닉변 감지만 더해진 형태입니다.
// deno/node 어느 쪽에서도 동작. zip 해제는 유틸로 먼저 수행.
import { readFile } from 'node:fs/promises';
type Entry = {
title: string;
media_list_data: unknown[];
string_list_data: Array<{ href: string; value: string; timestamp: number }>;
};
type FollowersFile = { relationships_followers: Entry[] };
type FollowingFile = { relationships_following: Entry[] };
const parseUsername = (e: Entry) => e.string_list_data[0]?.value ?? '';
async function analyze(followersPath: string, followingPath: string) {
const [fRaw, gRaw] = await Promise.all([
readFile(followersPath, 'utf8'),
readFile(followingPath, 'utf8'),
]);
const followersFile = JSON.parse(fRaw) as FollowersFile;
const followingFile = JSON.parse(gRaw) as FollowingFile;
const followers = new Set(followersFile.relationships_followers.map(parseUsername));
const following = new Set(followingFile.relationships_following.map(parseUsername));
// 내가 팔로우 중인데 상대는 나를 팔로우 안 함
const notFollowingBack = [...following].filter((u) => !followers.has(u));
// 나를 팔로우 중인데 나는 팔로우 안 함
const fans = [...followers].filter((u) => !following.has(u));
// 맞팔
const mutual = [...following].filter((u) => followers.has(u));
return { notFollowingBack, fans, mutual };
}
// 사용 예
analyze('followers_1.json', 'following.json').then((r) => {
console.log('맞팔 아님:', r.notFollowingBack.length);
console.log('팬(논맞팔):', r.fans.length);
console.log('맞팔:', r.mutual.length);
});toLowerCase()를 거는 편이 안전합니다./_u/ 뒤 경로와 현재 Instagram에서 resolve되는 값이 다르면 닉변입니다. CheckMate는 이 감지 로직을 별도로 운영합니다.CheckMate는 이 ZIP을 서버에 올리지 않고 브라우저에서 직접 해제·파싱합니다. 핵심 파일 경로는 connections/followers_and_following/ 하위이며, 업로드된 ZIP의 분할된 followers 파일을 전부 합친 뒤 username을 소문자 정규화하고, 위 예제처럼 차집합을 계산합니다. 그 외의 파일(likes, comments, saved 등)은 사용자가 허용한 경우에만 인사이트 대시보드로 분석합니다.
로그인·자동화·서버 저장 없이 로컬에서 처리하는 이유는 두 가지입니다. 하나는 프라이버시, 또 하나는 — 뒤에서 다룰 — Instagram의 쉐도우밴 리스크를 회피하기 위해서입니다. 로그인 자격증명을 받는 순간 자동화 트리거가 발생할 수 있기 때문에, 이 툴은 의도적으로 그 선을 넘지 않습니다. 관련 내용은 Shadowban 회피와 안전한 언팔 패턴 글에서 자세히 다룹니다.
아니요. Instagram이 보내는 다운로드 링크 자체가 본인 계정에서만 접근 가능한 개인 URL이라, ZIP 파일에 별도 암호는 걸려 있지 않습니다. 단, 다운로드한 파일을 타인에게 보내면 곧바로 읽을 수 있으니 보관에 주의하세요.
같은 기간에서 요청하면 거의 동일합니다. 단, followers의 ~365일 절단은 "요청 시점 기준"이라 어제 받은 ZIP과 오늘 받은 ZIP의 followers 리스트가 1~2명 차이날 수 있습니다.
CheckMate 기준으로는 followers_*.json 한 개 이상 + following.json 이 있으면 됩니다. ZIP을 통째로 올려도 되고, 압축을 풀어 JSON만 골라 올려도 됩니다.
저장되지 않습니다. 브라우저에서 파싱해 결과만 보여주고, 탭을 닫으면 휘발됩니다. 자세한 처리 원칙은 FAQ 에 정리해 두었습니다.