TikTok 的item_search_video接口是按关键词批量检索平台视频列表的核心工具,支持按地区、发布时间、互动量、内容类型、带货属性等多维度筛选,返回视频基础信息、互动数据、创作者信息、商品标签等关键内容,适配跨境内容聚合、爆款视频挖掘、带货效果分析、社媒舆情监测等场景。本攻略从接口认知、权限获取、实操对接、调试排错到生产级优化,提供全流程结构化指导,兼顾入门易用性与企业级稳定性,助力开发者高效完成跨境对接。
一、接口核心认知:功能与适配场景
1. 接口定位与核心价值
2. 核心参数与返回字段
(1)请求参数(必填 + 可选,按优先级排序)
(2)返回核心字段(按业务场景分类)
3. 接口限制与注意事项
二、对接前准备:权限与环境搭建
1. 获取接口权限(两条合规路径)
2. 技术环境准备
(1)支持语言与协议
(2)必备工具与依赖
三、实操步骤:接口对接全流程(Python 示例)
步骤 1:理解认证与签名规则
(1)官方接口 OAuth2.0 授权流程
(2)第三方接口签名规则(MD5 加密)
步骤 2:完整代码实现(第三方签名 + 官方 OAuth2.0 双示例)
(1)依赖安装
(2)第三方签名方式代码(快速接入)
import requests
import hashlib
import time
import json
import pandas as pd
import logging
from urllib.parse import urlencode
# 日志配置
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s",
handlers=[logging.FileHandler("tiktok_item_search_video.log"), logging.StreamHandler()]
)
# 接口配置(替换为自身信息)
CONFIG = {
"key": "你的第三方key",
"secret": "你的第三方secret",
"api_url": "https://api.example.com/tiktok/item_search_video",
"save_path": "TikTok视频搜索列表.xlsx"
}
def generate_sign(params: dict, secret: str) -> str:
"""生成第三方接口签名(MD5 32位大写)"""
params.pop("sign", None)
sorted_params = sorted(params.items(), key=lambda x: x[0])
param_str = urlencode(sorted_params, encoding="utf-8") + f"&secret={secret}"
md5 = hashlib.md5()
md5.update(param_str.encode("utf-8"))
return md5.hexdigest().upper()
def standardize_video_data(raw_video: dict) -> dict:
"""标准化视频数据,统一输出格式"""
create_time = raw_video.get("create_time", 0)
create_time_str = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(create_time)) if create_time else ""
duration = raw_video.get("duration", 0)
duration_str = f"{duration//60}:{duration%60:02d}"
return {
"搜索关键词": raw_video.get("keyword", ""),
"视频ID": raw_video.get("video_id", ""),
"标题": raw_video.get("title", ""),
"封面链接": raw_video.get("cover_url", ""),
"时长": duration_str,
"发布时间": create_time_str,
"地区": raw_video.get("region", ""),
"语言": raw_video.get("language", ""),
"播放量": raw_video.get("play_count", 0),
"点赞数": raw_video.get("like_count", 0),
"评论数": raw_video.get("comment_count", 0),
"分享数": raw_video.get("share_count", 0),
"收藏数": raw_video.get("favorite_count", 0),
"创作者ID": raw_video.get("author_id", ""),
"创作者昵称": raw_video.get("author_name", ""),
"认证状态": "认证" if raw_video.get("author_verified", 0) else "未认证",
"话题标签": ",".join(raw_video.get("hashtags", [])),
"商品数量": len(raw_video.get("products", [])) if raw_video.get("products") else 0,
"视频状态": "正常" if raw_video.get("status", 0) == 0 else "已下架/违规",
"请求时间": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
}
def tiktok_item_search_video(
keyword: str,
region: str = "global",
time_range: str = "all",
sort_type: str = "relevance",
has_product: int = 0,
page_no: int = 1,
page_size: int = 20
) -> dict:
"""调用TikTok item_search_video接口(第三方签名方式)"""
# 校验参数
if time_range == "custom" and not (start_date and end_date):
logging.error("time_range=custom时,start_date和end_date为必填参数")
return {"success": False, "error_msg": "缺少自定义时间参数"}
# 构建基础参数
params = {
"key": CONFIG["key"],
"keyword": keyword,
"region": region,
"time_range": time_range,
"sort_type": sort_type,
"has_product": has_product,
"page_no": page_no,
"page_size": page_size,
"timestamp": int(time.time() * 1000)
}
# 补充自定义时间参数
if time_range == "custom":
params["start_date"] = start_date
params["end_date"] = end_date
# 生成签名
params["sign"] = generate_sign(params, CONFIG["secret"])
try:
response = requests.post(
url=CONFIG["api_url"],
data=json.dumps(params),
headers={"Content-Type": "application/json"},
timeout=20,
verify=True
)
response.raise_for_status()
result = response.json()
if result.get("code") == 0 or result.get("status") == "success":
raw_data = result.get("data", {})
video_list = raw_data.get("item_list", [])
total = raw_data.get("total", 0)
page_total = raw_data.get("page_total", 1)
# 标准化数据
standard_videos = []
for video in video_list:
video["keyword"] = keyword
standard_videos.append(standardize_video_data(video))
return {
"success": True,
"data": standard_videos,
"total": total,
"page_total": page_total,
"error_msg": ""
}
else:
error_msg = result.get("msg", result.get("message", "接口调用失败"))
logging.error(f"接口返回错误(关键词:{keyword}):{error_msg}(code={result.get('code')})")
return {"success": False, "error_msg": error_msg}
except requests.exceptions.RequestException as e:
logging.error(f"网络请求异常(关键词:{keyword}):{str(e)}")
return {"success": False, "error_msg": f"网络异常:{str(e)}"}
except Exception as e:
logging.error(f"数据解析异常(关键词:{keyword}):{str(e)}")
return {"success": False, "error_msg": f"解析异常:{str(e)}"}
# 调用示例
if __name__ == "__main__":
# 单页获取示例:搜索“smartphone review”,美国地区,近30天,按播放量排序
single_page_result = tiktok_item_search_video(
keyword="smartphone review",
region="US",
time_range="30days",
sort_type="play",
page_size=20
)
if single_page_result["success"]:
print(f"获取到 {len(single_page_result['data'])} 条视频数据")
for video in single_page_result["data"][:5]:
print(f"标题:{video['标题']} | 播放量:{video['播放量']} | 创作者:{video['创作者昵称']}")
else:
print(f"单页获取失败:{single_page_result['error_msg']}")(3)官方接口 OAuth2.0 调用示例(核心片段)
from jose import jwt
import requests
def get_access_token(client_id, client_secret, code, redirect_uri):
"""通过授权码获取access_token"""
url = "https://open-api.tiktok.com/oauth/access_token/"
data = {
"client_id": client_id,
"client_secret": client_secret,
"code": code,
"grant_type": "authorization_code",
"redirect_uri": redirect_uri
}
response = requests.post(url, data=data)
return response.json().get("access_token")
def tiktok_official_item_search(access_token, keyword, region, sort_type):
"""调用TikTok官方视频搜索接口"""
url = "https://open-api.tiktok.com/video/search/"
headers = {"Authorization": f"Bearer {access_token}"}
params = {
"keyword": keyword,
"region": region,
"sort_type": sort_type,
"page_size": 20,
"fields": "id,title,cover_image_url,duration,stats,author,products"
}
response = requests.get(url, headers=headers, params=params)
return response.json()