使用 Python 爬取 TikTok 评论的实现与解析

news/2025/3/29 0:21:53/

在今天的博客中,我将分享如何使用 Python 爬取 TikTok 视频的评论信息。通过构建一个简单的爬虫,我们可以抓取 TikTok 上某个视频的所有评论,并将其保存到 CSV 文件中。以下是详细的代码实现与解释。

一、引入必要的库

在代码开始的部分,我们导入了几个关键的 Python 库:

python">import time
import requests
import execjs
import pandas as pd
from datetime import datetime
from urllib.parse import urlencode
from loguru import logger
  • time:用于时间操作。
  • requests:处理 HTTP 请求,获取数据。
  • execjs:用于执行 JavaScript 代码,帮助加密请求参数。
  • pandas:用于处理数据并将数据保存为 CSV 文件。
  • datetime:用于获取当前时间并进行格式化。
  • urlencode:用于对 URL 参数进行编码。
  • loguru:用于日志记录,帮助我们调试和记录程序运行的状态。

二、定义 TiktokUserSearch

我们通过一个名为 TiktokUserSearch 的类来实现爬虫的主体逻辑。该类负责初始化请求的参数、发送 HTTP 请求、解析数据以及保存评论。

1. 初始化请求头和 Cookie

首先,在类的初始化方法中,我们设置了请求头(self.headers)和 Cookie(self.cookies),用于模拟浏览器访问 TikTok。

python">class TiktokUserSearch:def __init__(self, output_file=None):self.headers = {"authority": "www.tiktok.com","accept": "*/*","accept-language": "zh-CN,zh;q=0.9,en;q=0.8","user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36"}self.cookies = Noneself.output_file = output_file if output_file else f'tiktok_comments_{datetime.now().strftime("%Y%m%d_%H%M%S")}.csv'
  • self.headers 包含了用户代理(User-Agent)和其他常见的 HTTP 请求头部信息。
  • self.cookies 用于存储用户的登录信息。
  • self.output_file 用于设置输出文件的文件名,默认为 tiktok_comments_时间.csv 格式。
2. cookie_str_to_dict 方法

这个方法用于将传入的 Cookie 字符串转换成字典格式,方便在请求中使用。

python">def cookie_str_to_dict(self, cookie_str) -> dict:cookie_dict = {}cookies = [i.strip() for i in cookie_str.split('; ') if i.strip() != ""]for cookie in cookies:key, value = cookie.split('=', 1)cookie_dict[key] = valuereturn cookie_dict
3. 发送 GET 请求

get 方法是用来发送 HTTP 请求并获取评论数据的。根据传入的 cursor 参数(分页标识符),我们构建请求参数并发送请求。

python">def get(self, cursor, cookie_str):self.cookies = self.cookie_str_to_dict(cookie_str)url = "https://www.tiktok.com/api/comment/list/"params = { ... }x_b = execjs.compile(open('./encrypt.js', encoding='utf-8').read()).call("sign", urlencode(params), self.headers["user-agent"])params.update({"X-Bogus": x_b})response = requests.get(url,headers=self.headers,cookies=self.cookies,params=params,timeout=(3, 10),proxies=None)return response.json()
  • cookie_str 用于设置请求的 Cookie。
  • 通过调用 JavaScript 文件 encrypt.js 中的 sign 方法对请求参数进行加密。
  • requests.get 发送 GET 请求获取 TikTok 的评论数据。
4. 解析和保存评论数据

parse_and_save_comments 方法用于解析返回的 JSON 数据,并将评论信息提取后保存到 CSV 文件。

python">    def parse_and_save_comments(self, data):"""解析评论数据并保存到CSV文件,保存所有可用字段:param data: API返回的评论数据"""if 'comments' not in data:logger.error("没有找到评论数据")returncomments_list = []for comment in data['comments']:# 解析每条评论的所有可用字段comment_data = {# 评论基本信息'comment_id': comment['cid'],'text': comment['text'],'create_time': datetime.fromtimestamp(comment['create_time']).strftime('%Y-%m-%d %H:%M:%S'),'digg_count': comment['digg_count'],'reply_count': comment['reply_comment_total'],'is_author_digged': comment.get('is_author_digged', False),'aweme_id': comment.get('aweme_id', ''),'stick_position': comment.get('stick_position', 0),'is_sticky': comment.get('is_sticky', False),'label_list': str(comment.get('label_list', [])),# 用户信息'user_nickname': comment['user']['nickname'],'user_id': comment['user']['uid'],'unique_id': comment['user'].get('unique_id', ''),'user_sec_uid': comment['user'].get('sec_uid', ''),'user_avatar_thumb': comment['user'].get('avatar_thumb', {}).get('url_list', [None])[0],'user_signature': comment['user'].get('signature', ''),'user_verified': comment['user'].get('verified', False),'user_follow_status': comment['user'].get('follow_status', 0),'user_follower_count': comment['user'].get('follower_count', 0),'user_following_count': comment['user'].get('following_count', 0),'user_total_favorited': comment['user'].get('total_favorited', 0),# 评论状态信息'status': comment.get('status', 0),'trans_btn_style': comment.get('trans_btn_style', 0),'text_extra': str(comment.get('text_extra', [])),'comment_language': comment.get('comment_language', ''),# 标记是否为回复评论'is_reply': False,'parent_comment_id': '','parent_comment_user_id': '','parent_comment_user_nickname': ''}# 添加回复评论(如果有)if comment.get('reply_comment'):for reply in comment['reply_comment']:reply_data = {# 回复评论基本信息'comment_id': reply['cid'],'text': f"[回复] {reply['text']}",'create_time': datetime.fromtimestamp(reply['create_time']).strftime('%Y-%m-%d %H:%M:%S'),'digg_count': reply['digg_count'],'reply_count': 0,'is_author_digged': reply.get('is_author_digged', False),'aweme_id': reply.get('aweme_id', ''),'stick_position': reply.get('stick_position', 0),'is_sticky': reply.get('is_sticky', False),'label_list': str(reply.get('label_list', [])),# 回复用户信息'user_nickname': reply['user']['nickname'],'user_id': reply['user']['uid'],'unique_id': reply['user'].get('unique_id', ''),'user_sec_uid': reply['user'].get('sec_uid', ''),'user_avatar_thumb': reply['user'].get('avatar_thumb', {}).get('url_list', [None])[0],'user_signature': reply['user'].get('signature', ''),'user_verified': reply['user'].get('verified', False),'user_follow_status': reply['user'].get('follow_status', 0),'user_follower_count': reply['user'].get('follower_count', 0),'user_following_count': reply['user'].get('following_count', 0),'user_total_favorited': reply['user'].get('total_favorited', 0),# 回复评论状态信息'status': reply.get('status', 0),'trans_btn_style': reply.get('trans_btn_style', 0),'text_extra': str(reply.get('text_extra', [])),'comment_language': reply.get('comment_language', ''),# 标记为回复评论,并添加父评论信息'is_reply': True,'parent_comment_id': comment['cid'],'parent_comment_user_id': comment['user']['uid'],'parent_comment_user_nickname': comment['user']['nickname']}# 如果回复中包含被回复用户信息if 'reply_to_reply_id' in reply:reply_data.update({'reply_to_reply_id': reply.get('reply_to_reply_id', ''),'reply_to_username': reply.get('reply_to_username', ''),'reply_to_user_id': reply.get('reply_to_userid', '')})comments_list.append(reply_data)comments_list.append(comment_data)
  • comments_list 存储所有评论(包括回复评论)。
  • 通过 pandas.DataFrame 将评论数据转化为表格格式并保存为 CSV 文件。

三、主程序执行流程

在主程序中,我们设置了输出文件名和 Cookie 字符串,然后调用 get 方法获取评论数据,并将数据传递给 parse_and_save_comments 方法进行解析和保存。

python">if __name__ == '__main__':output_file = 'tiktok_comments_output.csv'tiktok = TiktokUserSearch(output_file=output_file)cookie_str = 'your_cookie_string_here'cursor = '0'data = tiktok.get(cursor, cookie_str)if 'error' not in data:result = tiktok.parse_and_save_comments(data)logger.info(f"评论获取结果:")else:logger.error(f"获取评论失败:{data['error']}")

结果:

四、注意事项

  1. Cookie 获取:由于 TikTok 的 API 需要通过登录的 Cookie 才能获取评论,因此需要提供有效的 Cookie。可以通过浏览器的开发者工具获取 Cookie 字符串。
  2. 请求加密:TikTok 对请求参数进行了加密,使用 execjs 库执行 JavaScript 代码来加密请求参数。
  3. 分页机制:TikTok 的评论数据是分页的,每次请求会返回一个 cursor,表示下一页数据的位置。如果有更多数据,使用该 cursor 进行下一次请求。
  4. 错误处理:代码中包含了简单的错误处理机制,当请求发生网络错误时,会进行重试,最多重试三次。

五、总结

通过本文介绍的 TikTok 评论爬虫,您可以方便地抓取 TikTok 上的视频评论,并将其保存到本地进行进一步分析或存档。希望本文能对你有所帮助!


http://www.ppmy.cn/news/1583136.html

相关文章

【蓝桥杯】每日练习 Day10

目录 前言 空调 分析 代码 棋盘 分析 代码 重新排序 分析 代码 牛的学术圈I 分析 代码 日志统计 分析 代码 火柴排队 分析 代码 前言 复习第十天了,虽然每天都勤勤恳恳的做题但是发现好像没有什么成长,每次感觉有些进步了去比赛结果…

Atlas 800I A2 双机直连部署DeepSeek-R1-w8a8

一、环境信息 1.1、硬件信息 Atlas 800I A2 * 2 1.2、环境信息 操作系统:openEuler 22.03 LTS NPU驱动:Ascend-hdk-910b-npu-driver 24.1.0 linux-aarch64.run NPU固件:Ascend-hdk-910b-npu-firware 7.5.0.3.220.run MindIE镜像&#xff…

Excel第41套全国人口普查

2. 导入网页中的表格:数据-现有链接-考生文件夹:网页-找到表格-点击→变为√-导入删除外部链接关系:数据-点击链接-选中连接-删除-确定(套用表格格式-也会是删除外部链接)数值缩小10000倍(除以10000即可&am…

[MySQL#1] database概述 常见的操作指令 MySQL架构 存储引擎

#1024程序员节|征文# 目录 一. 数据库概念 0.连接服务器 1. 什么是数据库 口语中的数据库 为什么数据不直接以文件形式存储,而需要使用数据库呢? 总结 二. ??基础操作 三. 主流数据库 四. 基础知识 服务器,数据库&…

Java 项目 IntelliJ IDEA 多环境配置详解

目录 一、使用 Maven Profiles 实现多环境配置1. 在 `pom.xml` 中配置 Profiles2. 创建多环境配置文件3. 配置文件内容示例`application.properties``application-dev.properties``application-test.properties``application-prod.properties`4. 在代码中获取配置5. 激活 Maven…

数据结构-----树

一、树的基本概念 1. 树的结构定义 递归定义: 空树(n0)非空树(n≥1): 唯一根结点m个互不相交的子树(m≥0) 2. 核心术语 术语说明图示示例结点的度结点的子树个数树的度树中所有…

LeetCode 热题 100----2.移动零

LeetCode 热题 100----2.移动零 题目描述 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。请注意 ,必须在不复制数组的情况下原地对数组进行操作。示例 1:输入: nums [0,1,0,3,12] 输出: [1,3,12,…

requestAnimationFrame和requestIdleCallback分别是什么,是用在什么场景下

深入解析 requestAnimationFrame 和 requestIdleCallback requestAnimationFrame (rAF) 和 requestIdleCallback (rIC) 都是浏览器提供的 异步调度 API,但它们的执行时机和用途完全不同。 API主要用途何时执行是否保证执行适合场景requestAnimationFrame高优先级 U…