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 동영상을 크롤링할까?
사용자 1명당 하루 평균 이 재생되고, 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 / 데이터 없음 | JavaScript로 렌더링되는 콘텐츠; 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은 거의 모든 페이지 로드 시점에 __UNIVERSAL_DATA_FOR_REHYDRATION__라는 id를 가진 <script> 태그 안에 방대한 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
4> This paragraph contains content that cannot be parsed and has been skipped.
5resp = 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"팔로워 수: {stats['followerCount']}, 좋아요 수: {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에서 시작하며, 각 응답마다 다음 cursor 값이 반환됨)count— 페이지당 항목 수(보통 30~35개)
단계별: Python으로 TikTok 내부 API 호출하기
1단계: 대상 프로필의 secUid를 가져옵니다.
숨겨진 JSON(방법 1) 또는 프로필 페이지 HTML에서 확인할 수 있습니다.
2단계: API 요청을 구성하고 전송합니다.
1import requests
2import json
3> This paragraph contains content that cannot be parsed and has been skipped.
4resp = requests.get(api_url, params=params, headers=headers)
5data = 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)}")
각 반복마다 다음 묶음과 새로운 cursor가 반환됩니다. 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
4> This paragraph contains content that cannot be parsed and has been skipped.
5 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단계: 위의 세 가지 방법 중 하나로 동영상 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
2> This paragraph contains content that cannot be parsed and has been skipped.
3resp = requests.get(video_url, headers=headers, stream=True)
3단계: 응답 내용을 .mp4 파일로 저장합니다.
stream=True를 사용하고 chunk 단위로 기록하세요. 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 크롤링 프로젝트를 처음 시작했을 때 이런 비교표가 있었으면 좋았겠다 싶었던 표입니다.
This paragraph contains content that cannot be parsed and has been skipped.
제 추천은 다음과 같습니다.
- 한 프로필의 빠른 스냅샷만 필요하다면? 방법 1부터 시작하세요. 세팅은 30초 정도면 되고, 페이지당 1초도 안 되어 데이터를 받을 수 있습니다.
- 페이지네이션이 있는 프로필 전체 영상이 필요하다면? 방법 2가 적합하지만, TikTok이 API 파라미터를 바꿀 때마다 유지보수가 필요하다는 점은 감안해야 합니다.
- 로그인 벽, CAPTCHA, 또는 최대한의 안정성이 필요하다면? Playwright를 쓰는 방법 3이 좋습니다. 느리고 무겁지만, TikTok이 막기 가장 어려운 방식입니다.
실무에서는 보통 방법 1로 시작하고, 한계에 부딪힐 때만 방법 2나 3으로 올립니다. 이렇게 하면 인프라도 단순하고 비용도 낮게 유지할 수 있습니다.
Python이 꼭 필요하지 않다면? 노코드 도구로 TikTok 동영상 크롤링하기
"Python으로 TikTok 동영상 크롤링"을 검색하는 많은 분들은 사실 Python 자체가 아니라 데이터만 필요합니다. 몇 개의 경쟁사 프로필에서 영상 메타데이터를 가져오려는 마케팅 분석가나, 브랜드 언급을 추적하는 브랜드 매니저라면 프록시 로테이션과 서명 처리까지 포함한 Python 환경을 직접 구성하는 건 과합니다.

접근 방식별로 솔직하게 비교하면 아래와 같습니다.
| 방식 | 기술 수준 | 비용 | 유지보수 | 추천 대상 |
|---|---|---|---|---|
| Python(직접 구현) | 중급 이상 | 무료(+프록시 비용) | 높음(스크립트가 자주 깨짐) | 완전한 제어, 맞춤형 파이프라인 |
| Thunderbit(Chrome 확장 프로그램) | 초급 | 무료 플랜 제공 | 없음(AI가 매번 새로 읽음) | 빠른 영상 데이터 추출, Sheets/Excel로 내보내기 |
| Apify TikTok Scraper | 초급 | 유료(실행당 과금) | 낮음(Apify가 유지보수) | 일정에 맞춘 대량 자동 실행 |
| TikAPI | 개발자 | 유료 구독 | 중간 | TikTok 데이터 기반 앱 개발 |
Thunderbit가 TikTok 크롤링을 처리하는 방식
는 Thunderbit에서 만든 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 크롤링은 계속 변하는 타깃입니다. TikTok의 봇 방지 체계는 웹에서 가장 정교한 수준 중 하나이며, 단순한 방법(평범한 requests, ChatGPT가 생성한 코드 조각, 오래된 튜토리얼)은 실패할 가능성이 높습니다. 하지만 올바른 방식을 쓰면 충분히 가능합니다.
핵심만 정리하면 다음과 같습니다.
- **방법 1(숨겨진 JSON)**은 가장 빠르고 간단합니다. 빠른 프로필 수집은 여기서 시작하세요.
- **방법 2(내부 API)**는 페이지네이션과 대량 수집에 유리하지만, 엔드포인트와 서명 요구사항이 자주 바뀌므로 유지보수가 가장 많이 필요합니다.
- **방법 3(Playwright)**는 봇 방어에 가장 강하지만, 속도와 리소스 사용량을 감수해야 합니다.
- 세 가지 방법 모두 동영상 다운로드 URL을 추출할 수 있으며, 이 가이드는 올바른 헤더로 실제 .mp4 파일을 다운로드하는 과정까지 안내하는 거의 유일한 자료입니다.
- 비개발자라면, 가 코드를 작성하거나 유지보수하지 않고도 같은 데이터를 얻는 더 빠른 길이 될 수 있습니다. AI 기반 접근 방식이라 TikTok 레이아웃이 바뀌어도 잘 깨지지 않습니다. 커뮤니티 보고를 보면 이런 변경은 꽤 자주 일어납니다.
Python 설정 없이 바로 시작하고 싶다면, — 무료 플랜만으로도 몇 개 프로필에 테스트해 보고 업무 흐름에 맞는지 확인하기에 충분합니다. Python으로 가려는 분들은 방법 1부터 시작해 데이터를 검증한 뒤, 필요에 따라 확장해 나가면 됩니다.
웹 스크래핑 기술을 더 깊게 배우고 싶다면 , , 도 함께 확인해 보세요.
자주 묻는 질문(FAQs)
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)은 실제 브라우저 세션을 흉내 내기 때문에 차단 회피력이 가장 높습니다. 규모가 커질수록 프록시 비용을 예산에 넣어야 하며, 주요 제공업체의 입문형 주거용 프록시는 수준입니다.
- 더 알아보기