jsonscraper
市场
返回期刊

TikTok:将搜索结果转化为每周支持主题清单

Python 脚本收集搜索到的视频,统一处理两种 API 响应格式,并生成供人工标注的问题表格。

编辑政策 报告错误

支持团队需要一份公开 TikTok 视频清单,其中包含人们讨论不清楚的功能或询问产品的内容。手动搜索难以保持一致,而搜索 API 的响应可能会将视频存放在 JSON 的不同位置。下面这个简易 Python 脚本会按关键词查询结果、合并两种数据结构、按 ID 去重,并将找到的记录保存为 CSV。

脚本会生成什么结果

最终会得到一张表格,包含视频 ID、链接、描述、发布时间、作者以及可获取的互动计数。支持团队或营销团队可以手动标记哪些主题需要答复、更新说明或在自己的 CRM 中核查。表格仅反映 API 针对指定查询返回的结果;应将其视为供审阅的工作样本,而不是所有相关讨论的完整目录。

文章:TikTok:将搜索结果转化为每周支持主题清单
摘要:按产品相关查询定期收集 TikTok 视频,生成去重后的 CSV,其中包含链接、描述和可获取的公开指标。支持团队可以借助这份清单梳理主题,并结合现有资料和客户咨询进行核查。
图片用途:封面——核心概念
章节:脚本会生成什么结果
视觉主题:编辑风格照片,实体
重复出现的搜索结果会汇总成一份可核查的支持主题审阅队列。© jsonscraper · AI 生成

该脚本负责收集和初步整理。它不会自动判断描述属于提问、投诉还是玩笑:最好在人工核查后添加标签,或使用单独的分类器,同时记录原始文本和判断依据。

查询内容与响应结构

jsonscraper 文档介绍了用于搜索视频的 GET 路由 /searchVideo,主机为 https://tiktok.evelode.com。必需参数是 keyword;还可以传入 count、地区、排序方式、发布时间范围和下一页游标。例如,可以针对几个预先确定的短语重复搜索:功能名称、常见错误描述,以及简短的设置问题。参数及其允许值列于TikTok API 参考文档中。

搜索结果有一个需要解析器注意的特点:aweme_list 数组可能为空,而找到的视频对象则位于 search_item_list 中,每个条目内含有 aweme_info。因此,下面的处理程序会检查这两种结构。响应示例以及 2026 年 10 月 25 日检查时观察到的字段,见 jsonscraper 原始规范;统计字段可能缺失,因此代码不会填入虚构值。

准备密钥和查询列表

将密钥保存在环境变量 JSONSCRAPER_TIKTOK_LICENSE_KEY 中,而不要写入源文件。在 Linux 或 macOS 的 shell 中,可以这样设置:

export JSONSCRAPER_TIKTOK_LICENSE_KEY="你的密钥"

安装 requests 库,并创建 queries.txt 文件,每行填写一个搜索短语,例如 产品名称 设置 和 功能名称 无法使用。应根据受众使用的语言选择措辞,并将查询单独保存,以便每周导出时使用相同的查询进行比较。

python -m pip install requests

收集并统一处理找到的视频

示例兼容 Python 3.8 及以上版本。它会针对每个短语按结果数量限制发起一次请求,检查 HTTP 错误和顶层状态,然后仅保存实际存在的字段。重复结果会按 aweme_id 合并;所有找到该视频的查询都会记录在 keywords 字段中。单独的 collected_at_utc 字段会记录数据获取时间,便于与之后的运行结果比较。

文章:TikTok:将搜索结果转化为每周支持主题清单
摘要:按产品相关查询定期收集 TikTok 视频,生成去重后的 CSV,其中包含链接、描述和可获取的公开指标。支持团队可以借助这份清单梳理主题,并结合现有资料和客户咨询进行核查。
图片用途:配图 2——另一个具体方面
章节:收集并统一处理找到的视频
示意图展示了搜索响应的两种结构、搜索标签的合并,以及导出 CSV 前记录收集时间的过程。© jsonscraper · AI 生成插图
import csv
import os
import sys
from datetime import datetime, timezone

import requests

BASE_URL = "https://tiktok.evelode.com/searchVideo"
API_KEY = os.environ.get("JSONSCRAPER_TIKTOK_LICENSE_KEY")

if not API_KEY:
    raise SystemExit("请设置 JSONSCRAPER_TIKTOK_LICENSE_KEY")


def get_items(tiktok):
    """从文档所述的两种搜索响应结构中提取视频。"""
    items = list(tiktok.get("aweme_list") or [])
    for entry in tiktok.get("search_item_list") or []:
        info = entry.get("aweme_info") if isinstance(entry, dict) else None
        if info:
            items.append(info)
    return items


with open("queries.txt", encoding="utf-8") as query_file:
    queries = [line.strip() for line in query_file if line.strip()]

collected_at = datetime.now(timezone.utc).isoformat()
videos = {}

for keyword in queries:
    response = requests.get(
        BASE_URL,
        params={
            "license_key": API_KEY,
            "keyword": keyword,
            "count": 30,
            "region": "US",
            "sort_by": "relevance",
        },
        timeout=30,
    )
    response.raise_for_status()
    payload = response.json()

    if payload.get("status") != "ok":
        print("API 状态未成功,查询词:", keyword, file=sys.stderr)
        continue

    tiktok = payload.get("tiktok") or {}
    for item in get_items(tiktok):
        video_id = item.get("aweme_id")
        if not video_id:
            continue

        if video_id not in videos:
            author = item.get("author") or {}
            stats = item.get("statistics") or {}
            videos[video_id] = {
                "aweme_id": video_id,
                "keywords": [keyword],
                "description": item.get("desc"),
                "share_url": item.get("share_url"),
                "create_time": item.get("create_time"),
                "author": author.get("unique_id") or author.get("nickname"),
                "play_count": stats.get("play_count"),
                "digg_count": stats.get("digg_count"),
                "comment_count": stats.get("comment_count"),
                "share_count": stats.get("share_count"),
                "collected_at_utc": collected_at,
            }
        elif keyword not in videos[video_id]["keywords"]:
            videos[video_id]["keywords"].append(keyword)

columns = [
    "aweme_id", "keywords", "description", "share_url", "create_time",
    "author", "play_count", "digg_count", "comment_count", "share_count",
    "collected_at_utc",
]
with open("tiktok_support_review.csv", "w", newline="", encoding="utf-8-sig") as output:
    writer = csv.DictWriter(output, fieldnames=columns)
    writer.writeheader()
    for video in videos.values():
        row = dict(video)
        row["keywords"] = " | ".join(row["keywords"])
        writer.writerow(row)

print("找到并保存的唯一视频数:", len(videos))

请求通过 params 参数发送,因此该库会正确地将文本短语编码进 URL。密钥位于 query 参数中,符合文档说明;不要在应用日志中打印完整请求 URL。排查问题时,可以记录 HTTP 响应代码、查询短语名称和运行时间,但应排除与任务无关的密钥和个人数据。

解读 CSV,避免得出错误结论

keywords 列包含找到该视频的所有短语;collected_at_utc 可用于区分发布时间和收集时间。ID 便于去重,链接则用于人工核查。计数器为空表示该字段未出现在特定响应中,并不意味着数值为零。

如需进行初步分类,可在 CSV 工作副本中添加 主题、信号类型、需要回复 和 内部资料链接 等列。主题选项应与产品相符,例如安装、付款、兼容性或错误排查。这样的结构可以将导出结果转化为审阅队列,同时保留根据原始视频核查判断的可能性。

按计划运行收集任务

首先手动运行脚本,并检查若干行记录和链接。然后将其加入 cron、CI 任务或能够运行 Python 进程的自动化流程。若要生成定期报告,可以保存每次导出结果,或将数据追加到以视频唯一键和快照日期为标识的存储中。这样,团队就能区分新发现的发布内容和重复观察,并追踪不同运行期间可用计数的变化。

搜索提供了 cursor 参数用于翻页;传入时必须使用上一次调用响应中的值。这个简易示例有意不包含分页:限制查询集更便于检查和复现。如果要添加分页,应原样保存游标,在没有更多结果时停止,并为每次运行设置调用次数上限。API 请求返回的是一个样本;不要将行数理解为 TikTok 的完整覆盖范围。

实际应用边界

搜索结果适合根据团队已知的措辞发现视频。它有助于收集分类材料,但不能替代客户来信、自己网站的分析数据或对视频上下文的核查。描述可能未包含视频的核心内容,且可用指标反映的是数据获取时的状态。请将主题和结论与原始字段分开记录,以便员工重新审视分类结果。

在启动定期监测前,应确定谁有权访问导出数据、数据保留多久以及公开信息将用于何种目的。只保存产品审阅所需的字段,并优先保留原始帖子的链接,而不是复制媒体文件。如需提交请求并核查可用的集成方式,请查看 TikTok Scraper API 页面以及搜索路由文档。

继续阅读如何在导入 CRM 前核验 TikTok 线索的 IG 账号
阅读下一篇文章

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

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

查看 API