TikTok의 월간 활성 사용자는 현재 약 에 달하고, 크리에이터들은 매일 추정치로 2,300만 개의 영상을 올립니다. 이 엄청난 데이터 흐름의 일부라도 모아보려 했다면, 그게 얼마나 손이 많이 가는 일인지 이미 잘 아실 겁니다.
보통은 이렇게 시작됩니다. “Python으로 TikTok 동영상 스크래핑”을 검색하고, 튜토리얼에서 코드 조각을 복사해 오거나 ChatGPT에 코드를 짜 달라고 한 다음 실행해 보면… 아무것도 안 나옵니다. 빈 HTML, 403 에러, 아니면 가장 허탈한 “Process finished with exit code 0”인데 출력은 0개. GitHub 이슈와 Reddit 스레드에서 이 과정을 수십 번이나 봤고, 바로 그 이유 때문에 이 가이드를 만들었습니다. 여기서는 2025년 기준 실제로 작동하는 Python 방법 3가지와, 메타데이터가 아니라 진짜 .mp4 동영상 파일을 다운로드하는 전체 과정까지 다룹니다. 또 다른 튜토리얼들은 대부분 여기서 끝나지만, 이 글은 한 걸음 더 나아가 비교표까지 제공해 어떤 방식이 내 상황에 맞는지 고를 수 있게 해 드립니다. Python이 꼭 필요하지 않다면, 같은 노코드 대안도 함께 소개합니다. 클릭 두 번이면 같은 데이터를 얻을 수 있습니다.
"TikTok 동영상 스크래핑"은 실제로 무슨 뜻일까?
코드를 보기 전에, 사람들이 “TikTok 동영상을 스크래핑한다”고 할 때 정확히 뭘 뜻하는지 먼저 짚고 넘어갈 필요가 있습니다. 이 표현은 사실 아주 다른 두 가지를 포함하거든요.
- 동영상 메타데이터 추출: 설명문, 해시태그, 좋아요 수, 댓글 수, 공유 수, 조회수, 게시일, 작성자 정보. 대부분의 튜토리얼은 여기까지만 다룹니다.
- 실제 동영상 파일(.mp4) 다운로드: 동영상 자체를 내 컴퓨터에 저장하는 것. 사실 대부분의 사람들이 “TikTok 동영상 스크래핑”을 검색할 때 진짜 원하는 건 이 부분인데, 거의 아무도 이걸 제대로 설명해 주지 않습니다.
이 가이드는 두 가지를 모두 다룹니다. 아래의 모든 방법은 메타데이터를 추출할 수 있을 뿐 아니라, .mp4 파일을 저장하는 데 필요한 다운로드 URL도 얻을 수 있습니다.
왜 Python으로 TikTok 동영상을 스크래핑할까?
사용자당 하루 평균 , TikTok Shop은 전 세계 광고 매출 을 만들어 내고 있습니다. 즉, TikTok 데이터에 접근할 이유는 분명합니다. 가장 흔한 활용 사례는 다음과 같습니다.
| 활용 사례 | 수집하는 데이터 | 주 사용자 | |---|---|---| | 인플루언서 및 마케팅 리서치 | 참여율, 팔로워 수, 콘텐츠 형식, 해시태그 성과 | 마케팅 팀, 에이전시 | | 콘텐츠 전략 수립 | 유행 해시태그, 바이럴 동영상 형식, 게시 빈도 | 크리에이터, 소셜 미디어 매니저 | | 브랜드 모니터링 | 언급량, 캠페인 도달 범위, 잠재고객 반응 | 브랜드 매니저, PR 팀 | | 경쟁사 분석 | 경쟁사 영상 성과, 광고 소재, TikTok Shop 상품 목록 | 이커머스, 제품 팀 | | 시장 조사 | 떠오르는 트렌드, 사용자 행동, 상품 발견 패턴 | 분석가, 헤지펀드, 리서치 회사 | | 보관 및 컴플라이언스 | 내부 검토나 기록 보존용 동영상 파일 | 법무, 컴플라이언스, 에이전시 |
상업적 가치도 큽니다. 미국 TikTok 광고 매출은 2026년에 234억 달러까지 성장할 것으로 예상되며, 제휴 크리에이터는 상위 TikTok Shop 카테고리에서 를 만들어 냅니다. 이커머스나 인플루언서 마케팅 분야라면, 이 데이터는 곧바로 돈의 가치로 연결됩니다.
기본 Python 코드가 TikTok에서 실패하는 이유
아래처럼 시도해 봤는데도 아무 결과가 없었다면, 혼자가 아닙니다.
1import requests
2from bs4 import BeautifulSoup
3resp = requests.get("https://www.tiktok.com/@someuser")
4soup = BeautifulSoup(resp.text, "html.parser")
5# ...그리고 HTML 안에는 쓸 만한 데이터가 아무것도 없음
이유는 단순합니다. TikTok은 스크래핑하기 가장 어려운 플랫폼 중 하나입니다. 기본적인 requests.get()은 실제 콘텐츠가 없는 빈 HTML 껍데기만 돌려주는데, 핵심 데이터는 브라우저 안에서 JavaScript로 렌더링되기 때문입니다. 게다가 TikTok은 행동 감지, TLS 핑거프린팅, 요청 서명을 생성하는 , 그리고 예고 없이 바뀌는 동적 CSS 셀렉터까지 포함한 강력한 봇 차단 체계를 운영합니다.

Imperva 2025 Bad Bot Report에 따르면 2024년에는 처음으로 자동 트래픽이 사람 트래픽을 넘어섰고, 현재 봇은 를 차지합니다. TikTok도 이런 상황을 잘 알고 있으며, 이에 맞게 방어 체계를 구축해 두었습니다.
무엇이 문제인지 빠르게 진단할 수 있도록 아래 표를 참고해 보세요.
| 증상 | 가능한 원인 | 해결 방법 |
|---|---|---|
| 빈 HTML / 데이터 없음 | JS 렌더링 콘텐츠; requests는 JavaScript를 실행하지 못함 | 방법 1(숨겨진 JSON) 또는 방법 3(Playwright) |
| 403 / 접근 거부 | 헤더 누락 또는 오류; 봇 차단 감지 | 적절한 헤더를 사용한 방법 1 |
| 처음엔 되다가 이후 멈춤 | 요청 제한 / IP 차단 | 프록시 로테이션(모든 방법) |
| 로그인 벽이 나타남 | 세션/쿠키 필요 | 방법 3(저장된 세션이 있는 브라우저) |
| ChatGPT가 만든 코드가 아무것도 못 가져옴 | 모델 학습 이후 TikTok 구조가 바뀜 | 최신 방식인 3가지 방법 모두 |
요청 제한은 대략 IP당 분당 30~60회 정도를 넘기면 소프트 블록이나 CAPTCHA가 뜨기 시작합니다. 데이터센터 IP는 몇 분 만에 걸러지므로, 어느 정도 규모가 있다면 주거용 또는 모바일 프록시는 사실상 필수입니다.
Python으로 TikTok 동영상을 스크래핑하는 3가지 방법 한눈에 보기
이 글의 전체 로드맵입니다. 각 방법은 장단점이 다르며, 아래에서 모두 실제 코드와 함께 설명합니다.
- 숨겨진 JSON 추출 — TikTok 페이지에 포함된
__UNIVERSAL_DATA_FOR_REHYDRATION__스크립트 태그를 파싱합니다. 가장 빠르고 단순하며, 브라우저가 필요 없습니다. - TikTok 내부 API — 문서화되지 않은
/api/post/item_list/엔드포인트를 직접 호출해 커서 기반 페이지네이션으로 대량 데이터를 가져옵니다. - Playwright를 이용한 브라우저 자동화 — 헤드리스 브라우저에서 페이지를 렌더링해 무한 스크롤, 동적 콘텐츠, 로그인 벽까지 처리합니다.
세 방법 모두 실제 .mp4 동영상 파일 다운로드에 사용할 수 있습니다. 이 부분은 각 방법 설명 뒤 별도 섹션에서 자세히 다룹니다. 마지막에는 비교표도 있으니, 상황에 맞는 방식을 고르시면 됩니다.
방법 1: 숨겨진 JSON으로 TikTok 동영상 스크래핑하기(초보자 친화적)
처음 시작할 때 가장 추천하는 방법입니다. TikTok은 거의 모든 페이지 로드 시 <script> 태그 안에 __UNIVERSAL_DATA_FOR_REHYDRATION__라는 id로 거대한 JSON 덩어리를 넣어 둡니다. 이 JSON에는 프런트엔드 JavaScript가 원래 렌더링할 프로필 및 동영상 데이터가 모두 들어 있으므로, 브라우저 없이 HTTP 요청 한 번으로 가져올 수 있습니다.
필요한 것
- Python 3.8+
requests(또는httpx)beautifulsoup4(또는parsel)- 올바른 헤더:
User-Agent,Referer,Accept-Language
의존성을 설치합니다.
1pip install requests beautifulsoup4
단계별: 스크립트 태그에서 TikTok 동영상 데이터 추출하기
1단계: 실제 브라우저처럼 보이는 헤더로 GET 요청 보내기.
대부분의 초보자가 여기서 막힙니다. 헤더 없이 requests.get()만 보내면 TikTok은 403이나 CAPTCHA 페이지를 돌려줍니다. 최소한 최신 브라우저의 User-Agent와 Referer 헤더는 넣어야 합니다.
1import requests
2from bs4 import BeautifulSoup
3import json
4url = "https://www.tiktok.com/@charlidamelio"
5headers = {
6 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
7 "Referer": "https://www.tiktok.com/",
8 "Accept-Language": "en-US,en;q=0.9",
9}
10resp = requests.get(url, headers=headers)
2단계: HTML을 파싱하고 hydration 스크립트 태그를 찾기.
1soup = BeautifulSoup(resp.text, "html.parser")
2script_tag = soup.find("script", id="__UNIVERSAL_DATA_FOR_REHYDRATION__")
script_tag가 None이라면, TikTok이 차단했거나(상태 코드를 확인하세요) 스크립트 태그 ID를 바꾼 것입니다(드물지만 가능).
3단계: 스크립트 내용을 JSON으로 읽기.
1data = json.loads(script_tag.string)
4단계: JSON 구조를 따라가며 동영상 메타데이터 추출하기.
구조는 __DEFAULT_SCOPE__ 아래에 중첩되어 있습니다. 사용자 프로필 페이지라면 다음과 같이 접근합니다.
1user_detail = data["__DEFAULT_SCOPE__"]["webapp.user-detail"]
2user_info = user_detail["userInfo"]
3# 프로필 통계
4stats = user_info["stats"]
5print(f"Followers: {stats['followerCount']}, Likes: {stats['heartCount']}")
6# 동영상 목록(첫 페이지)
7item_list = user_detail.get("itemList", [])
8for video in item_list:
9 print(video["desc"]) # 캡션
10 print(video["stats"]["playCount"]) # 조회수
11 print(video["video"]["playAddr"]) # 동영상 다운로드 URL(워터마크 없음)
12 print(video["video"]["downloadAddr"]) # 동영상 다운로드 URL(워터마크 포함)
5단계: 동영상 다운로드 URL 추출하기.
playAddr 필드는 보통 더 깔끔한 버전의 동영상을 제공합니다(대개 TikTok 워터마크가 없거나 덜한 버전). 반면 downloadAddr는 일반적인 워터마크가 들어간 주소입니다. 둘 다 .mp4 파일로 바로 연결되는 URL이지만, 다운로드할 때는 특정 헤더가 필요합니다(아래 다운로드 섹션에서 다룹니다).
이제 각 동영상의 캡션, 통계, 생성 시간, 해시태그(challenges[]와 textExtra에 포함), 직접 동영상 URL이 들어 있는 메타데이터 객체 목록을 얻을 수 있습니다.
숨겨진 JSON 방식의 한계
- 초기 페이지 로드 데이터만 가져올 수 있음 — 보통 프로필의 첫 30개 정도 동영상만 가능
- 무한 스크롤이나 페이지네이션을 처리할 수 없음(요청할 "다음 페이지"가 없음)
- TikTok이 스크립트 태그 ID나 JSON 구조를 바꾸면 파서가 깨짐(주기적으로 발생하며, 같은 검증이 조기 탐지에 도움됨)
- 적합한 경우: 빠른 프로필 스크래핑, 일회성 데이터 수집, 최신 영상만 필요할 때
방법 2: 내부 API로 TikTok 동영상 스크래핑하기
TikTok 프런트엔드는 한 번에 모든 동영상을 불러오지 않습니다. 스크롤할 때마다 내부 API 엔드포인트로 XHR 요청을 보내는 방식입니다. 사용자 동영상에 가장 많이 쓰이는 엔드포인트는 /api/post/item_list/입니다. 이 주소를 Python에서 직접 호출하면 커서 기반 페이지네이션을 이용해 프로필의 모든 동영상에 접근할 수 있습니다(첫 페이지만이 아닙니다).
내부 API 엔드포인트 찾는 법
TikTok 프로필 페이지에서 Chrome DevTools를 열고 Network 탭으로 이동한 뒤 XHR로 필터링하고 아래로 스크롤해 보세요. 다음과 비슷한 URL로 요청이 나가는 것을 볼 수 있습니다.
1https://www.tiktok.com/api/post/item_list/?WebIdLastTime=...&aid=1988&count=35&cursor=0&secUid=...
핵심 파라미터는 다음과 같습니다.
secUid— 프로필의 고유 ID(방법 1의 JSON에서userInfo.user.secUid로 추출 가능)cursor— 페이지네이션 오프셋(0부터 시작하며, 각 응답이 다음 커서 값을 돌려줌)count— 페이지당 항목 수(보통 30~35개)
단계별: Python으로 TikTok 내부 API 호출하기
1단계: 대상 프로필의 secUid 가져오기.
방법 1의 숨겨진 JSON이나 프로필 페이지 HTML에서 추출할 수 있습니다.
2단계: API 요청 구성 및 전송.
1import requests
2import json
3sec_uid = "MS4wLjABAAAA..." # 방법 1에서 가져옴
4api_url = "https://www.tiktok.com/api/post/item_list/"
5params = {
6 "aid": "1988",
7 "secUid": sec_uid,
8 "count": 35,
9 "cursor": 0,
10}
11headers = {
12 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Gecko/20100101 Firefox/124.0",
13 "Referer": "https://www.tiktok.com/",
14}
15resp = requests.get(api_url, params=params, headers=headers)
16data = resp.json()
3단계: 응답 파싱하기.
data["itemList"]의 각 항목에는 방법 1과 동일한 동영상 구조가 들어 있습니다. desc, stats, video.playAddr, video.downloadAddr 등이 포함됩니다.
4단계: 모든 동영상에 대해 페이지네이션하기.
1all_videos = []
2cursor = 0
3has_more = True
4while has_more:
5 params["cursor"] = cursor
6 resp = requests.get(api_url, params=params, headers=headers)
7 data = resp.json()
8 items = data.get("itemList", [])
9 all_videos.extend(items)
10 has_more = data.get("hasMore", False)
11 cursor = data.get("cursor", 0)
12 print(f"{len(items)}개 동영상 가져옴, 총합: {len(all_videos)}, hasMore: {has_more}")
13print(f"총 스크래핑한 동영상 수: {len(all_videos)}")
각 반복마다 다음 배치와 새 커서가 반환됩니다. hasMore가 False가 될 때까지 반복하면 됩니다.
내부 API 방식의 한계
- TikTok은 이 엔드포인트와 필요한 파라미터를 자주 바꾸므로, 유지보수 부담이 가장 큽니다. 최근에는 일부 요청에
msToken,X-Bogus같은 서명 파라미터가 필요해졌는데, 이는 TikTok의 이 생성합니다(즉, 이를 순수 Python으로 그대로 재현하는 건 만만치 않습니다). - 특정 데이터 타입은 세션 쿠키나 추가 토큰이 필요할 수 있음
- IP 기반 요청 제한은 여전히 적용됨 — 프록시 로테이션 권장
itemList배열이 비어 나오기 시작하면 보통msToken이 만료된 것입니다(브라우저에서는 대략 10초마다 회전)- 적합한 경우: 프로필의 모든 동영상을 대량으로 가져와야 하고, 방법 1의 첫 페이지만으로는 부족할 때
방법 3: Playwright로 TikTok 동영상 스크래핑하기(브라우저 자동화)
처음 두 방법이 로그인 요구, CAPTCHA, 재현하기 어려운 서명 파라미터 때문에 막히면 Playwright가 대안입니다. 실제 브라우저(헤드리스)를 띄워 인간 사용자처럼 TikTok을 탐색하므로, JavaScript 렌더링, 무한 스크롤, 인증된 세션까지 처리할 수 있습니다.
TikTok 스크래핑용 Playwright 설정하기
Playwright와 브라우저 바이너리를 설치합니다.
1pip install playwright
2playwright install firefox
TikTok 스크래핑에는 Chromium보다 Firefox를 추천합니다. 커뮤니티 테스트에서 Firefox가 을 보였고, TikTok의 봇 탐지는 Chromium 계열 헤드리스 브라우저에 특히 더 공격적이기 때문입니다.
추가적인 은폐가 필요하다면 (Playwright 수정 포크) 또는 (C++ 수준에서 안티디텍션을 적용한 Firefox)와 함께 사용하는 것도 고려해 볼 수 있습니다. 에 따르면 Camoufox는 주요 봇 탐지 서비스에 대해 거의 완벽한 스텔스 점수를 기록합니다.
단계별: Playwright로 TikTok 프로필 동영상 스크래핑하기
1단계: 헤드리스 Firefox 브라우저를 실행하고 프로필로 이동하기.
1import asyncio
2from playwright.async_api import async_playwright
3import json
4async def scrape_tiktok_profile(username):
5 async with async_playwright() as p:
6 browser = await p.firefox.launch(headless=True)
7 context = await browser.new_context(
8 user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0",
9 viewport={"width": 1280, "height": 720},
10 )
11 page = await context.new_page()
12 await page.goto(f"https://www.tiktok.com/@{username}", wait_until="networkidle")
2단계: 동영상 그리드가 로드될 때까지 기다리기.
1 # 동영상 항목이 나타날 때까지 대기
2 await page.wait_for_selector('[data-e2e="user-post-item"]', timeout=15000)
TikTok에 "Something went wrong" 오버레이가 뜨면 재시도 버튼을 눌러야 할 수 있습니다.
1 retry_btn = page.locator('button:has-text("Retry")')
2 if await retry_btn.count() > 0:
3 await retry_btn.click()
4 await page.wait_for_selector('[data-e2e="user-post-item"]', timeout=15000)
3단계: 숨겨진 JSON에서 데이터 추출하기(Playwright에서도 마찬가지).
가장 안정적인 방식은 브라우저를 사용하더라도 여전히 hydration JSON을 읽는 것입니다.
1 script_el = page.locator("#__UNIVERSAL_DATA_FOR_REHYDRATION__")
2 raw_json = await script_el.inner_text()
3 data = json.loads(raw_json)
4 # 방법 1과 동일한 JSON 탐색
5 user_detail = data["__DEFAULT_SCOPE__"]["webapp.user-detail"]
6 videos = user_detail.get("itemList", [])
4단계: 더 많은 동영상을 위해 무한 스크롤 처리하기.
초기 30개 정도를 넘어 더 많이 필요하다면, 아래로 스크롤하면서 추가 XHR 응답을 캡처하면 됩니다.
1 all_videos = list(videos)
2 # 스크롤하면서 API 응답 가로채기
3 api_responses = []
4 async def capture_response(response):
5 if "/api/post/item_list" in response.url:
6 try:
7 body = await response.json()
8 api_responses.append(body)
9 except:
10 pass
11 page.on("response", capture_response)
12 # 더 많은 로드를 유도하기 위해 아래로 스크롤
13 for _ in range(5): # 필요에 따라 스크롤 횟수 조정
14 await page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
15 await asyncio.sleep(2)
16 # 가로챈 응답에서 동영상 수집
17 for api_resp in api_responses:
18 items = api_resp.get("itemList", [])
19 all_videos.extend(items)
20 print(f"총 동영상 수: {len(all_videos)}")
21 await browser.close()
22 return all_videos
23# 실행
24videos = asyncio.run(scrape_tiktok_profile("charlidamelio"))
이제 초기 페이지 로드와 스크롤로 추가 로드된 페이지까지 포함한 동영상 객체 목록을 얻을 수 있습니다.
Playwright 방식의 한계
- 세 방법 중 가장 느림(전체 페이지 렌더링, 네트워크 왕복, 스크롤 지연 포함)
- 리소스 사용량이 큼 — 브라우저 인스턴스마다 메모리와 CPU를 상당히 사용함
- 대규모로 돌릴 때는 IP 차단의 영향을 받을 수 있음 — 프록시 로테이션 병행 필요
- 적합한 경우: 복잡한 상호작용, 로그인 벽이 있는 콘텐츠, CAPTCHA 대응, 또는 방법 1과 2가 막혔을 때
Python으로 TikTok 동영상(.mp4) 다운로드하는 방법
이 부분이야말로 다른 모든 TikTok 스크래핑 튜토리얼에서 가장 크게 빠져 있는 내용입니다. 메타데이터 추출도 유용하지만, “TikTok 동영상 스크래핑”을 검색하는 많은 사람들은 실제 동영상 파일을 원합니다.
TikTok은 동영상 데이터 객체 안에 다운로드 URL을 포함합니다.
playAddr— 보통 워터마크가 없거나 덜한 버전downloadAddr— TikTok 앱 내 다운로드용으로 제공하는 버전(틱톡 워터마크 오버레이 포함)
두 URL 모두 유효 기간이 짧고 금방 만료됩니다(보통 몇 시간 수준). 따라서 추출한 직후 바로 다운로드해야 합니다.
단계별: TikTok 동영상 파일 다운로드하기
1단계: 위 3가지 방법 중 하나로 동영상 URL을 추출하기.
1video_url = video["video"]["playAddr"] # 워터마크 없음
2# 또는
3video_url = video["video"]["downloadAddr"] # 워터마크 포함
2단계: 올바른 헤더로 GET 요청 보내기.
여기서 많은 분들이 막힙니다. 그냥 requests.get(video_url)를 호출하면 403이 뜹니다. TikTok은 Referer 헤더를 확인하고 브라우저처럼 보이는 User-Agent를 기대합니다.
1import requests
2headers = {
3 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
4 "Referer": "https://www.tiktok.com/",
5}
6resp = requests.get(video_url, headers=headers, stream=True)
3단계: 응답 내용을 .mp4 파일로 저장하기.
stream=True를 사용하고 청크 단위로 저장하세요. TikTok 동영상은 용량이 클 수 있으므로 전체 파일을 메모리에 올릴 필요가 없습니다.
1video_id = video["id"]
2filename = f"tiktok_{video_id}.mp4"
3with open(filename, "wb") as f:
4 for chunk in resp.iter_content(chunk_size=1024 * 1024): # 1MB 청크
5 if chunk:
6 f.write(chunk)
7print(f"다운로드 완료: {filename}")
이제 로컬 컴퓨터에서 재생 가능한 .mp4 파일을 갖게 됩니다.
워터마크 버전 vs. 무워터마크 버전
TikTok은 각 동영상에 대해 워터마크가 있는 버전과 없는 버전을 모두 저장합니다. playAddr URL은 보통 더 깔끔한 버전(플레이어가 사용하는 버전)을 제공하고, downloadAddr는 크리에이터의 사용자명이 들어간 TikTok 워터마크 오버레이가 포함됩니다.
여기서 윤리적인 부분도 짚고 넘어가야 합니다. 워터마크는 크리에이터 표시를 위한 것입니다. 연구, 분석, 내부 검토 목적이라면 playAddr를 사용하는 것이 일반적으로 괜찮습니다. 하지만 콘텐츠를 재배포하거나 재업로드한다면, 크리에이터 표기를 제거하는 행위는 윤리적 문제와 저작권 문제를 동시에 불러올 수 있습니다. 법적 이슈는 아래 섹션에서 더 설명합니다.
더 안정적인 다운로드 파이프라인이 필요하다면 를 고려해 보세요. TikTok 추출기가 서명 계산과 URL 해석을 자동으로 처리해 주므로, 헤더나 토큰 만료를 직접 관리할 필요가 없습니다.
나란히 비교: 어떤 Python 방법을 써야 할까?
TikTok 스크래핑 프로젝트를 처음 시작했을 때 이런 비교표가 있었으면 좋겠다고 생각했던 내용입니다.
| 기준 | 방법 1: 숨겨진 JSON | 방법 2: 내부 API | 방법 3: Playwright |
|---|---|---|---|
| 난이도 | 초급 | 중급 | 중급 |
| 속도 | 빠름(페이지당 1회 요청) | 빠름(JSON API) | 느림(전체 페이지 렌더링) |
| 봇 차단 내성 | 중간 | 낮음(엔드포인트가 자주 바뀜) | 높음(실제 브라우저처럼 동작) |
| 동영상 .mp4 다운로드 가능? | 가능(playAddr 추출) | 가능(응답에 URL 포함) | 가능(네트워크 가로채기) |
| 무한 스크롤 처리 | 불가(첫 페이지만) | 가능(커서 페이지네이션) | 가능(스크롤 시뮬레이션) |
| 대규모 운영 시 프록시 필요 | 예 | 예 | 예 |
| 유지보수 필요성 | 중간(JSON 구조 변경) | 높음(엔드포인트/서명 변경이 잦음) | 낮음~중간(브라우저가 어느 정도 대응) |
| 가장 적합한 용도 | 빠른 단발성 프로필 스크래핑 | 대량 데이터 추출, 전체 동영상 수집 | 로그인 벽이 있거나 복잡한 콘텐츠 |
제 추천은 이렇습니다.
- 특정 프로필의 빠른 스냅샷만 필요하다면? 방법 1부터 시작하세요. 설정에 30초 정도면 충분하고, 페이지당 1초도 안 돼 데이터를 가져올 수 있습니다.
- 페이지네이션 포함해서 프로필의 모든 동영상이 필요하다면? 방법 2가 적합합니다. 다만 TikTok이 API 파라미터를 바꿀 때마다 유지보수가 필요할 수 있습니다.
- 로그인 벽, CAPTCHA, 또는 최대한 높은 안정성이 필요하다면? Playwright를 쓰는 방법 3이 좋습니다. 느리고 무겁지만, TikTok이 막기 가장 어려운 방식입니다.
실무에서는 보통 방법 1로 시작해서, 한계에 부딪히면 방법 2나 3으로 옮깁니다. 그래야 인프라는 단순하게 유지되고 비용도 낮습니다.
Python이 꼭 필요 없나요? 노코드 도구로 TikTok 동영상 스크래핑하기
“Python으로 TikTok 동영상 스크래핑”을 검색하는 많은 분들이 사실 Python이 필요한 게 아니라 데이터가 필요한 경우가 많습니다. 경쟁사 몇 개 프로필에서 영상 메타데이터를 가져오려는 마케팅 분석가이거나, 언급량을 추적하는 브랜드 매니저라면, 프록시 로테이션과 서명 처리까지 포함한 Python 환경을 직접 세팅하는 건 너무 과한 작업일 수 있습니다.

접근 방식별로 솔직하게 비교해 보면 다음과 같습니다.
| 접근 방식 | 기술 수준 | 비용 | 유지보수 | 적합한 경우 | |---|---|---|---|---| | Python(DIY) | 중급 이상 | 무료(+ 프록시 비용) | 높음(스크립트가 자주 깨짐) | 완전한 제어, 맞춤형 파이프라인 | | (Chrome 확장 프로그램) | 초보자 | 무료 플랜 제공 | 없음(AI가 매번 사이트를 새로 읽음) | 빠른 영상 데이터 추출, Sheets/Excel로 내보내기 | | Apify TikTok Scraper | 초보자 | 유료(실행당 과금) | 낮음(Apify가 관리) | 예약 실행이 필요한 대량 자동화 | | TikAPI | 개발자 | 유료 구독 | 중간 | TikTok 데이터 기반 앱 개발 |
Thunderbit가 TikTok 스크래핑을 처리하는 방식
는 우리가 만든 AI 웹 스크래퍼이며, 전통적인 스크래핑 도구와 방식이 다릅니다. 미리 만들어진 CSS 셀렉터나 XPath 규칙에 의존하지 않기 때문에(이 방식은 TikTok이 레이아웃을 바꿀 때마다 깨집니다), Thunderbit의 AI는 매번 페이지 구조를 새로 읽고 캡션, 좋아요 수, 해시태그, 동영상 URL, 작성자 등 필요한 열을 제안합니다.
실제 워크플로는 두 번의 클릭이면 됩니다.
- Chrome에서 TikTok 프로필로 이동한 뒤 Thunderbit 확장 프로그램을 클릭하고 “AI 필드 추천”을 누릅니다. Thunderbit가 페이지를 분석해 표 구조를 제안합니다.
- 제안된 열을 확인하고 필요하면 조정한 뒤 “스크래핑”을 클릭합니다.
데이터는 Google Sheets, Excel, Airtable, Notion으로 바로 내보낼 수 있습니다. CSS 셀렉터를 유지할 필요도 없고, 디버깅할 코드도 없고, 프록시 설정도 필요 없습니다. 몇 개 프로필에서 영상 메타데이터만 필요한 마케팅 분석가에게는, Python 환경을 세팅하는 것보다 훨씬 빠르며 TikTok이 프런트엔드를 업데이트해도 잘 깨지지 않습니다(커뮤니티 보고에 따르면, 이 변화는 몇 주마다 한 번씩 일어나기도 합니다).
Thunderbit는 도 지원합니다. 각 개별 동영상 페이지를 방문해 댓글 수, 음악 정보, 동영상 길이 같은 추가 정보로 데이터를 보강할 수 있습니다.
에서 무료로 사용해 볼 수 있습니다. 작동 방식이 더 궁금하다면 도 확인해 보세요.
TikTok 스크래핑 시 지켜야 할 법적·윤리적 기준
이 주제의 상위 노출 튜토리얼 중 합법성을 다루는 글은 거의 없지만, TikTok이 스크래핑 서비스에 대해 실제로 법적 대응을 해 온 점을 생각하면 중요한 누락입니다. 알아두어야 할 핵심은 다음과 같습니다.
**TikTok 이용약관(§ 4.1)**은 자동화된 접근을 명시적으로 금지합니다. 약관 위반은 형사 범죄는 아니지만 계약 위반이므로, 계정 정지, IP 차단, 민사 소송으로 이어질 수 있습니다.
공개 데이터에 대한 법적 환경은 많은 사람이 생각하는 것보다 관대한 편입니다. 대표적인 선례는 Meta Platforms v. Bright Data (캘리포니아 북부지법, 2024년 1월)로, 법원은 로그인하지 않은 상태에서 공개적으로 접근 가능한 데이터를 스크래핑하는 행위가 Meta의 이용약관을 위반하지 않는다고 판단했습니다. Meta는 소송을 철회하고 항소권도 포기했습니다. 그보다 앞선 hiQ v. LinkedIn 제9순회 판결(및 Van Buren 이후 재확인)은 공개 접근 가능한 데이터의 스크래핑이 CFAA 위반이 아님을 정립했습니다. 다만 hiQ는 결국 합의했고 50만 달러를 지불했으며 영구 금지명령에도 동의했기 때문에, 약관 집행의 리스크가 완전히 사라진 것은 아닙니다.
GDPR와 CCPA는 EU나 캘리포니아 사용자의 개인정보를 수집하는 경우 적용됩니다. 공개 게시물을 수집하는 것과, 개인 사용자들의 개인정보 데이터베이스를 만드는 것은 완전히 다른 문제입니다.
실무 가이드라인:
- 요청 속도를 조절하세요(TikTok 서버를 과도하게 두드리지 말 것)
- 비공개 계정이나 미성년자 콘텐츠는 스크래핑하지 마세요
- 저작권이 있는 동영상을 상업적으로 재배포하지 마세요
robots.txt를 존중하세요(TikTok은 대부분의 자동 크롤링을 막아 둠)- 개인 연구나 분석을 위한 다운로드와 재업로드는 다릅니다. 그 차이를 분명히 이해해야 합니다
면책 조항: 이 글은 교육 목적이며 법률 자문이 아닙니다. 스크래핑한 TikTok 데이터로 상업용 제품을 만들 계획이라면 변호사와 상담하세요.
마무리: 핵심 정리
2025년의 TikTok 스크래핑은 계속 변하는 과제입니다. 이 플랫폼의 봇 차단 체계는 웹에서 가장 정교한 수준에 속하며, 단순한 접근 방식(기본 requests, ChatGPT가 만들어 준 코드 조각, 오래된 튜토리얼)은 실패할 가능성이 큽니다. 하지만 올바른 방법을 쓰면 충분히 가능합니다.
핵심만 정리하면 다음과 같습니다.
- **방법 1(숨겨진 JSON)**은 가장 빠르고 단순합니다. 빠른 프로필 스크래핑은 여기서 시작하세요.
- **방법 2(내부 API)**는 페이지네이션과 대량 접근을 제공하지만, 엔드포인트와 서명 요구사항이 자주 바뀌어 유지보수가 가장 많이 필요합니다.
- **방법 3(Playwright)**는 봇 차단에 가장 강하지만, 속도와 리소스 사용 측면의 비용이 있습니다.
- 세 방법 모두 동영상 다운로드 URL을 추출할 수 있으며, 이 가이드는 올바른 헤더를 사용해 실제로 .mp4 파일을 다운로드하는 과정까지 안내하는 거의 유일한 글입니다.
- 비기술 사용자라면, 가 코드 작성이나 유지보수 없이 같은 데이터를 훨씬 빠르게 얻을 수 있는 방법입니다. AI 기반 접근 방식 덕분에 TikTok 레이아웃이 바뀌어도 잘 깨지지 않습니다. 커뮤니티 보고를 보면, 이 변화는 누구도 반가워하지 않을 만큼 자주 일어납니다.
Python을 따로 세팅하지 않고 바로 시작하고 싶다면 . 무료 플랜만으로도 몇 개 프로필을 시험해 보기엔 충분합니다. Python 방식으로 가신다면, 먼저 방법 1부터 시작해 데이터가 제대로 나오는지 확인한 뒤 확장해 나가세요.
웹 스크래핑 기술을 더 깊이 배우고 싶다면 , , 가이드도 함께 보시길 권합니다.
자주 묻는 질문(FAQ)
Python으로 TikTok 동영상을 스크래핑하는 것은 합법인가요?
공개적으로 접근 가능한 데이터를 스크래핑하는 것은 명확히 불법이라고 단정하기 어려운 회색지대입니다. Meta v. Bright Data (2024) 판결은 로그인하지 않은 상태에서 공개 데이터를 스크래핑하는 행위가 플랫폼 이용약관을 위반하지 않는다는 입장을 뒷받침합니다. 다만 TikTok의 약관은 자동화된 접근을 명시적으로 금지하고 있으며, 개인정보를 다룰 경우 GDPR/CCPA 의무도 적용됩니다. 대부분의 사람들이 두려워하는 방식으로 곧바로 불법은 아니지만, 위험이 전혀 없는 것도 아닙니다. 구체적인 용도라면 법률 전문가와 상담하세요.
TikTok 스크래핑에 가장 좋은 Python 라이브러리는 무엇인가요?
접근 방식에 따라 다릅니다. 숨겨진 JSON 추출(방법 1)이라면 requests + beautifulsoup4만으로 충분합니다. 내부 API 호출(방법 2)에는 requests나 httpx가 잘 맞습니다. 브라우저 자동화(방법 3)에는 현재 playwright가 표준이며, 새 스크래핑 프로젝트에서 Selenium보다 더 많이 채택되고 있습니다. 로 Selenium의 약 5,300만 회보다 많습니다. TikTok-Api 래퍼(깃허브 스타 약 6.3K)도 더 높은 수준의 인터페이스가 필요하다면 고려할 만하지만, 다소 불안정할 수 있습니다.
Python으로 워터마크 없는 TikTok 동영상을 다운로드할 수 있나요?
네. TikTok 자체 데이터에는 보통 표준 워터마크 오버레이가 없는 버전을 제공하는 playAddr URL이 포함되어 있습니다. 이 가이드에서는 세 가지 방법 중 어떤 방식으로든 해당 URL을 추출하고, 올바른 헤더로 .mp4 파일을 다운로드하는 방법을 설명합니다. 반대로 downloadAddr 필드에는 워터마크가 포함됩니다.
내 TikTok 스크래퍼가 빈 데이터를 돌려주는 이유는 무엇인가요?
가장 흔한 이유는 TikTok이 콘텐츠 렌더링에 JavaScript를 필요로 하기 때문입니다. 기본 requests.get()은 껍데기 HTML만 가져오고, 실제 데이터는 숨겨진 JSON 스크립트 태그(방법 1)에 있거나 JavaScript로 동적으로 로드됩니다(방법 3). 빈 HTML이 나온다면 먼저 방법 1을 시도하세요. 그래도 안 되면 헤더를 점검하고(Referer 누락은 403의 가장 흔한 원인입니다), 필요하면 Playwright를 사용하는 방법 3으로 넘어가세요.
TikTok 스크래핑 중 차단을 피하려면 어떻게 해야 하나요?
실제 브라우저처럼 보이는 헤더(User-Agent, Referer, Accept-Language 포함)를 사용하고, 주거용 또는 모바일 프록시를 순환하며(데이터센터 IP는 몇 분 내에 걸립니다), 요청 사이에 무작위 지연(최소 1~3초)을 넣고, 너무 높은 빈도로 스크래핑하지 마세요. 방법 3(Playwright)은 실제 브라우저 세션을 흉내 내므로 차단에 가장 강합니다. 어느 정도 규모 이상으로 운영할 계획이라면 프록시 비용을 반드시 고려해야 하며, 주요 공급업체의 초급형 주거용 프록시는 수준입니다.