使用 Python 爬取 TikTok 评论的实现与解析
在今天的博客中,我将分享如何使用 Python 爬取 TikTok 视频的评论信息。通过构建一个简单的爬虫,我们可以抓取 TikTok 上某个视频的所有评论,并将其保存到 CSV 文件中。以下是详细的代码实现与解释。
一、引入必要的库
在代码开始的部分,我们导入了几个关键的 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。
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 = None
self.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 字符串转换成字典格式,方便在请求中使用。
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] = value
return cookie_dict
3. 发送 GET 请求
get
方法是用来发送 HTTP 请求并获取评论数据的。根据传入的 cursor
参数(分页标识符),我们构建请求参数并发送请求。
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 文件。
def parse_and_save_comments(self, data):
"""
解析评论数据并保存到CSV文件,保存所有可用字段
:param data: API返回的评论数据
"""
if 'comments' not in data:
logger.error("没有找到评论数据")
return
comments_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
方法进行解析和保存。
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']}")
结果:
四、注意事项
- Cookie 获取:由于 TikTok 的 API 需要通过登录的 Cookie 才能获取评论,因此需要提供有效的 Cookie。可以通过浏览器的开发者工具获取 Cookie 字符串。
- 请求加密:TikTok 对请求参数进行了加密,使用
execjs
库执行 JavaScript 代码来加密请求参数。 - 分页机制:TikTok 的评论数据是分页的,每次请求会返回一个
cursor
,表示下一页数据的位置。如果有更多数据,使用该cursor
进行下一次请求。 - 错误处理:代码中包含了简单的错误处理机制,当请求发生网络错误时,会进行重试,最多重试三次。
五、总结
通过本文介绍的 TikTok 评论爬虫,您可以方便地抓取 TikTok 上的视频评论,并将其保存到本地进行进一步分析或存档。希望本文能对你有所帮助!