인스타그램의 릴스 다운 방지 기술과 싸운 기록

SeonDal·5일 전
0

🕊️ 기록기룩 

목록 보기
8/8
post-thumbnail

"인스타그램 동영상 다운 F12" 라는 키워드를 검색해보면
불과 3년 전만 해도

<video/> 태그 내에 있는 src url을 복사 붙여넣기 하는 간단한 방법으로 원 비디오 소스를 다운로드 받을 수 있다!

고 소개하는 블로그 글을 쉽게 볼 수 있다

근데 결론부터 말하자면 지금은 당연히 막혔다.
저작권 문제 떄문인지 성능 때문인지는 몰라도 인스타그램 공식에서 막아놓음

근데 궁금했다
어떻게 막았을까?


F12 개발자 도구를 켜봤다

1. Video tag src

<video class="x1lliihq x5yr21d xh8yej3" playsinline="" preload="none" src="blob:https://www.instagram.com/2e11c120-8e20-4312-a010-a6991a1c3013" style="display: block;"></video>

다짜고짜 video 태그부터 검색했다

blob:https://www.instagram.com/2e11c120-8e20-4312-a010-a6991a1c3013

blob으로 처리한 Url이 나온다.
Blob URL은 실제 비디오 파일을 가리키는 URL이 아니고 브라우저에서 메모리상으로 생성되는 임시 URL이다.
외부에서 직접 접근할 수 없으니 당연히 이 링크로 들어가서 동영상 '다른 이름으로 저장 ⭐️' 같은건 불가능.

5년 전까지만 해도 가능한 방법이였지만 야무지게 막혔다

2. cdn

cdninstagram.com 이 인스타그램의 모든 데이터가 들어있는 cdn의 url이다.

검색해보았지만 전무 .js .css .png .io 같은 정적 파일들만 있었다.
이미지 까지는 쉽게 다운 받을 수 있다.
하지만 내가 원하는 동영상에 대한 소스는 없었다

비디오 게시물에 해당하는 소스도 다 썸네일의 이미지 형태만 저장함..
영상도 저 cdn 안에 있는건 확실한데.. 어디에 있는걸까..

3. Network Tab

3년 전까지만 해도 네트워크 탭에서 Media 형태로 다운 받아지는 소스에 접근할 수 있었다고 한다
지금은? 막혔다
아무리 새로고침해도 텅 비어있는 네트워크 탭을 보니 마음이 아프다

하지만 분명 서버와 통신을 한다면 네트워크 탭에서 보여야한다.
인스타그램은 이 통신 과정을 어떻게 숨긴걸까?

4. /api/v1/feed/reels_tray

Fetch/XHR을 물론이고 All로 바꿔서 모든 통신 내역을 살펴봤지만 (너무 많기도 하고) 이렇다할 성과는 없었다...
고 하려던 중 수상한 Request URL을 발견했다

https://www.instagram.com/api/v1/feed/reels_tray/?is_following_feed=false

  • can_reply : 댓글 가능 여부
  • can_reshare : 재공유 가능 여부
  • seen: 조회수 (?)
    등.. 응답에 릴스와 관련된 필드들이 있는걸 보니 이건 릴스에 대한 정보인것 같다 🤔

그럼.. 영상 소스도 있지 않을까?
응답 링크에서 cdn 링크와 비디오 확장자 후보들을 다 검색해봐도 없었다

그러다가 뒤늦게 깨달음 : 이건 사용자 계정에 대한 api였다더라
인스타 계정의 primary key같은 TMI만 얻었다;;

아 근데 신기한거 하나를 알게 됐는데

"accessibility_caption": "Photo by ㅇㅇㅇ on January 23, 2025. 사람 6명, 연, 꽃, 풀밭, 피크닉 및 텍스트의 이미지일 수 있음.",

이런 신기한 필드가 있었다.
사진마다 다 분석해서 어떤 사진인지 정보를 accessibility_caption에 저장하는게 신기했다

5. url을 찾았으면 끝나나?

결국 릴스 비디오 원 링크를 찾지 못했다.
그리고 찾더라도 해결해야할 문제가 하나 있다

서버 통신으로 받아온 응답은 https://scontent-ssn1-1.cdninstagram.com/v/ 이런식으로 시작하는 cdn 링크를 포함하고 있는데,
서브도메인이 static이였던 링크와는 달리......
이 링크는 접근이 안된다

직접 접근하면 Bad URL hash라고 뜬다.
아무래도 인스타그램은 동적으로 URL을 생성하고 그 유효기간을 엄청 짧게 설정하는 것 같다. 나같은 사람이 CDN 링크를 통해 비디오 URL에 접근하는걸 막기 위해...
즉 내가 응답을 가로채서 링크를 통해 접근해도 만료되어서 접근할 수가 없음 💀


영 찝찝한 패배...
좀 더 공부해서 다시 돌아오마

까지 작성하고 아쉬운 마음에 좀 더 살펴보다가 유레카를 외쳤다

6. 응답을 JSON으로 파싱하기

출처 : https://github.com/postaddictme/instagram-php-scraper/issues/1134

인스타그램 스크래퍼 프로그램의 깃허브의 이슈에 나온 Q&A였는데
의도치않게 링크 뒤에 __a=1&__d=dis 를 쿼리로 붙여서 응답을 json으로 파싱한다는 걸 알게 되었다

어.. 그럼 설마..?

!!!! 내가 찾던 거다!
릴스에 대한 응답이 JSON으로 파싱된 버전이다 ㅋㅋㅋ

이후 이 응답에서 비디오에 해당하는 객체와 cdn 링크를 찾는건 매우 쉬웠다

cdn url로 들어가면 릴스 다운이 가능하다

성공 !

profile
김선달 개발블로그

1개의 댓글

comment-user-thumbnail
5일 전

재밌게 읽었습니다 !
accessibility_caption에 달아놓은 이미지 캡션들은 AI모델로 단거 같네요.. 추천시스템에 쓰이나봐요 ㄷㄷ

답글 달기