jsonscraper
市场
返回期刊

如何通过公开视频检查 TikTok 广告披露

Python 脚本按品牌关键词收集视频,标记明确的广告用语,并保存列表供人工审核

编辑政策 报告错误

要筛选提及品牌且含有明确广告用语的公开 TikTok 视频,可以使用多个搜索词收集结果、提取说明文字并标记关键词。最终生成的 CSV 文件包含视频链接和可用指标,可作为人工审核队列,而不是自动判定是否合规的结论。

这种流程适用于需要核对活动与简报是否一致的代理机构,也适用于维护公开提及列表的内部团队。它有助于整理搜索结果,并保留分析人员判断应打开哪些视频进行检查的依据。

具体要在视频中查找什么?

审核广告时,重要的是创作者与品牌之间的关联,以及这种关联是否在推荐内容附近得到披露。FTC 面向网红的指南解释,实质性关联可能涉及财务、工作、个人或家庭关系,披露应醒目且易于理解。对于视频推荐,FTC 指出,披露应出现在视频本身,而不能只放在说明文字中。因此,说明文字有助于筛选,但单凭它无法表明观众在画面中看到了什么或在音频中听到了什么。

此脚本的目标范围更窄:在返回的搜索结果中,找出说明文字含有品牌词组以及“广告”“赞助”或“合作”等潜在标记的视频。应根据活动所用语言和术语调整词表。如果说明文字中没有出现标记,请打开视频并检查其内容:文字匹配无法确定视频本身是否包含披露。

如何将搜索结果转化为审核队列?

先列出少量搜索词:品牌名称、活动名称以及常见的产品写法。分别运行每个搜索词,并将搜索词与结果一并保存。这样,团队就能知道视频是通过哪个搜索词找到的,并在需要时重新执行收集。

文章:如何通过公开视频检查 TikTok 广告披露
摘要:营销团队经常需要筛选提及品牌且可能包含广告披露的公开 TikTok 视频。本文介绍如何收集 API 返回结果、提取说明文字和可用指标,并标记“广告”“合作”等明确用语,以便后续审核。
图片用途:辅助插图 2——展示一个不同的具体方面
章节:如何将搜索结果转化为审核队列
示意图展示了从搜索结果到 CSV 审核队列,再到人工检查视频本身披露信息的流程。© jsonscraper · AI 生成插图
文章:如何通过公开视频检查 TikTok 广告披露
摘要:营销团队经常需要筛选提及品牌且可能包含广告披露的公开 TikTok 视频。本文介绍如何收集 API 返回结果、提取说明文字和可用指标,并标记“广告”“合作”等明确用语,以便后续审核。
图片用途:封面——核心主题
章节:如何将搜索结果转化为审核队列?
视觉主题:俄语信息图
示意图展示了从搜索结果到 CSV 审核队列,再到人工检查视频本身披露信息的流程。© jsonscraper · AI 生成

可以使用 jsonscraper 的 TikTok Scraper API进行收集。文档所述的 GET 路由 /searchVideo 位于 https://tiktok.evelode.com,接受 keyword、count、date_posted、sort_by、region 和 cursor 参数。在观察到的响应中,TikTok 数据中的视频位于 search_item_list[].aweme_info;aweme_list 可能为空。下面的解析器会检查这两种位置。

密钥通过 license_key 参数传递。请将其保存在环境变量中,而不要写进脚本或代码仓库。TikTok 路由文档列出了搜索参数名称;要获取下一页,请使用返回的 cursor。请保存已处理对象的数量和搜索词:分页可以继续获取结果,但本身并不能证明结果集完整。

Python 最简示例

该脚本针对每个词组发起一次请求,收集两种文档所述的结果格式,按视频 ID 去重,标记说明文字中的词语,并写入 CSV。使用命令 python -m pip install requests 安装 requests,在环境中设置 JSONSCRAPER_TIKTOK_LICENSE_KEY,然后运行文件。示例兼容 Python 3.8 及更高版本。

import csv
import os
import sys
import requests

BASE_URL = "https://tiktok.evelode.com/searchVideo"
KEY = os.environ.get("JSONSCRAPER_TIKTOK_LICENSE_KEY")
if not KEY:
    raise SystemExit("Set JSONSCRAPER_TIKTOK_LICENSE_KEY first")

QUERIES = ["Example Brand", "Example Product", "Example Campaign"]
MARKERS = ("#реклама", "реклама", "спонсор", "партнерство", "партнёрство", "#ad", "sponsored")


def videos_from(payload):
    data = payload.get("tiktok") or {}
    videos = data.get("aweme_list") or []
    if not videos:
        videos = [
            item.get("aweme_info")
            for item in (data.get("search_item_list") or [])
            if isinstance(item, dict) and isinstance(item.get("aweme_info"), dict)
        ]
    return [video for video in videos if isinstance(video, dict)]


rows = {}
for query in QUERIES:
    response = requests.get(
        BASE_URL,
        params={"keyword": query, "count": 20, "date_posted": "this-month", "license_key": KEY},
        timeout=30,
    )
    response.raise_for_status()
    payload = response.json()
    if payload.get("status") != "ok":
        print("Unexpected API status for query:", query, file=sys.stderr)
        continue

    for video in videos_from(payload):
        video_id = video.get("aweme_id")
        if not video_id:
            continue
        author = video.get("author") or {}
        stats = video.get("statistics") or {}
        caption = video.get("desc") or ""
        matched = [word for word in MARKERS if word in caption.casefold()]
        row = rows.setdefault(str(video_id), {
            "video_id": str(video_id),
            "url": video.get("share_url") or "",
            "author": author.get("unique_id") or author.get("nickname") or "",
            "caption": caption,
            "queries": set(),
            "disclosure_markers": set(),
            "play_count": stats.get("play_count"),
            "digg_count": stats.get("digg_count"),
            "comment_count": stats.get("comment_count"),
            "review_status": "manual_review",
        })
        row["queries"].add(query)
        row["disclosure_markers"].update(matched)

with open("tiktok_disclosure_review.csv", "w", newline="", encoding="utf-8-sig") as file:
    fields = ["video_id", "url", "author", "caption", "queries", "disclosure_markers",
              "play_count", "digg_count", "comment_count", "review_status"]
    writer = csv.DictWriter(file, fieldnames=fields)
    writer.writeheader()
    for row in rows.values():
        row["queries"] = " | ".join(sorted(row["queries"]))
        row["disclosure_markers"] = " | ".join(sorted(row["disclosure_markers"]))
        writer.writerow(row)

print("Saved", len(rows), "unique returned videos")

保存代码前,请检查外部响应的状态,然后检查 tiktok 中的数据。规范化器会读取这两种视频位置。若要请求下一页,可以将返回的 cursor 原样传入下一次请求;这个最简示例有意将每个搜索词限制为一页。

CSV 中会显示什么?

每一行将视频 ID 和链接、可用的作者标识、说明文字、搜索词以及匹配的标记关联起来。如果响应包含播放量、点赞数和评论数,这些指标会作为判断审核优先级的参考予以保存。这些字段可能缺失;脚本会将其留空,而不会填入零。

接下来打开视频,检查披露是否存在于视频中且足够醒目,并按照商定的类别记录结果,例如“已发现”“需要进一步审核”或“观看时未发现”。代码只会在说明文字中搜索精确的文本标记;它不会检查画面或音频,也不会判定是否符合规则。

如需定期执行,请按计划运行收集任务,记录请求时间,并将原始 JSON 与 CSV 一并保存。只保留必要的搜索词,并设定收集数据的保存期限。jsonscraper 负责任数据收集政策提到,应以合理频率发出请求、尽量减少数据收集,并在采取后续行动前核实 AI 结果。

最终得到的是一份可复现的公开视频人工审核队列,用于检查广告披露:搜索匹配项和可用指标有助于决定先打开哪些视频,而对视频本身的评估仍由审核人员完成。参数名称可在 TikTok API 文档中核对,产品信息则可查阅 TikTok Scraper API 页面。

人们

尚未列出本文的人员。

继续阅读TikTok:将搜索结果转化为每周支持主题清单
阅读下一篇文章

将阅读内容转化为可用的集成

探索 jsonscraper 社交数据 API、测试请求并构建下一个工作流。

查看 API