490 lines
27 KiB
Python
490 lines
27 KiB
Python
# ==============================================================================
|
||
# Copyright (C) 2021 Evil0ctal
|
||
#
|
||
# This file is part of the Douyin_TikTok_Download_API project.
|
||
#
|
||
# This project is licensed under the Apache License 2.0 (the "License");
|
||
# you may not use this file except in compliance with the License.
|
||
# You may obtain a copy of the License at:
|
||
# http://www.apache.org/licenses/LICENSE-2.0
|
||
#
|
||
# Unless required by applicable law or agreed to in writing, software
|
||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
# See the License for the specific language governing permissions and
|
||
# limitations under the License.
|
||
# ==============================================================================
|
||
# __
|
||
# /> フ
|
||
# | _ _ l
|
||
# /` ミ_xノ
|
||
# / | Feed me Stars ⭐ ️
|
||
# / ヽ ノ
|
||
# │ | | |
|
||
# / ̄| | | |
|
||
# | ( ̄ヽ__ヽ_)__)
|
||
# \二つ
|
||
# ==============================================================================
|
||
#
|
||
# Contributor Link:
|
||
# - https://github.com/Evil0ctal
|
||
# - https://github.com/Johnserf-Seed
|
||
#
|
||
# ==============================================================================
|
||
|
||
|
||
import asyncio # 异步I/O
|
||
import time # 时间操作
|
||
import yaml # 配置文件
|
||
import os # 系统操作
|
||
|
||
# 基础爬虫客户端和TikTokAPI端点
|
||
from crawlers.base_crawler import BaseCrawler
|
||
from crawlers.tiktok.web.endpoints import TikTokAPIEndpoints
|
||
from crawlers.utils.utils import extract_valid_urls
|
||
|
||
# TikTok加密参数生成器
|
||
from crawlers.tiktok.web.utils import (
|
||
AwemeIdFetcher,
|
||
BogusManager,
|
||
SecUserIdFetcher,
|
||
TokenManager
|
||
)
|
||
|
||
# TikTok接口数据请求模型
|
||
from crawlers.tiktok.web.models import (
|
||
UserProfile,
|
||
UserPost,
|
||
UserLike,
|
||
UserMix,
|
||
UserCollect,
|
||
PostDetail,
|
||
UserPlayList,
|
||
PostComment,
|
||
PostCommentReply,
|
||
UserFans,
|
||
UserFollow
|
||
)
|
||
|
||
|
||
# 配置文件路径
|
||
path = os.path.abspath(os.path.dirname(__file__))
|
||
|
||
# 读取配置文件
|
||
with open(f"{path}/config.yaml", "r", encoding="utf-8") as f:
|
||
config = yaml.safe_load(f)
|
||
|
||
|
||
class TikTokWebCrawler:
|
||
|
||
def __init__(self):
|
||
self.proxy_pool = None
|
||
|
||
# 从配置文件中获取TikTok的请求头
|
||
async def get_tiktok_headers(self):
|
||
tiktok_config = config["TokenManager"]["tiktok"]
|
||
kwargs = {
|
||
"headers": {
|
||
"User-Agent": tiktok_config["headers"]["User-Agent"],
|
||
"Referer": tiktok_config["headers"]["Referer"],
|
||
"Cookie": tiktok_config["headers"]["Cookie"],
|
||
},
|
||
"proxies": {"http://": None, "https://": None},
|
||
}
|
||
return kwargs
|
||
|
||
"""-------------------------------------------------------handler接口列表-------------------------------------------------------"""
|
||
|
||
# 获取单个作品数据
|
||
async def fetch_one_video(self, itemId: str):
|
||
# 获取TikTok的实时Cookie
|
||
kwargs = await self.get_tiktok_headers()
|
||
# 创建一个基础爬虫
|
||
base_crawler = BaseCrawler(proxies=kwargs["proxies"], crawler_headers=kwargs["headers"])
|
||
async with base_crawler as crawler:
|
||
# 创建一个作品详情的BaseModel参数
|
||
params = PostDetail(itemId=itemId)
|
||
# 生成一个作品详情的带有加密参数的Endpoint
|
||
endpoint = BogusManager.model_2_endpoint(
|
||
TikTokAPIEndpoints.POST_DETAIL, params.dict(), kwargs["headers"]["User-Agent"]
|
||
)
|
||
response = await crawler.fetch_get_json(endpoint)
|
||
return response
|
||
|
||
# 获取用户的个人信息
|
||
async def fetch_user_profile(self, secUid: str, uniqueId: str):
|
||
# 获取TikTok的实时Cookie
|
||
kwargs = await self.get_tiktok_headers()
|
||
# 创建一个基础爬虫
|
||
base_crawler = BaseCrawler(proxies=kwargs["proxies"], crawler_headers=kwargs["headers"])
|
||
async with base_crawler as crawler:
|
||
# 创建一个用户详情的BaseModel参数
|
||
params = UserProfile(secUid=secUid, uniqueId=uniqueId)
|
||
# 生成一个用户详情的带有加密参数的Endpoint
|
||
endpoint = BogusManager.model_2_endpoint(
|
||
TikTokAPIEndpoints.USER_DETAIL, params.dict(), kwargs["headers"]["User-Agent"]
|
||
)
|
||
response = await crawler.fetch_get_json(endpoint)
|
||
return response
|
||
|
||
# 获取用户的作品列表
|
||
async def fetch_user_post(self, secUid: str, cursor: int = 0, count: int = 35, coverFormat: int = 2):
|
||
# 获取TikTok的实时Cookie
|
||
kwargs = await self.get_tiktok_headers()
|
||
# proxies = {"http://": 'http://43.159.29.191:24144', "https://": 'http://43.159.29.191:24144'}
|
||
# 创建一个基础爬虫
|
||
base_crawler = BaseCrawler(proxies=None, crawler_headers=kwargs["headers"])
|
||
async with base_crawler as crawler:
|
||
# 创建一个用户作品的BaseModel参数
|
||
params = UserPost(secUid=secUid, cursor=cursor, count=count, coverFormat=coverFormat)
|
||
# 生成一个用户作品的带有加密参数的Endpoint
|
||
endpoint = BogusManager.model_2_endpoint(
|
||
TikTokAPIEndpoints.USER_POST, params.dict(), kwargs["headers"]["User-Agent"]
|
||
)
|
||
response = await crawler.fetch_get_json(endpoint)
|
||
return response
|
||
|
||
# 获取用户的点赞列表
|
||
async def fetch_user_like(self, secUid: str, cursor: int = 0, count: int = 30, coverFormat: int = 2):
|
||
# 获取TikTok的实时Cookie
|
||
kwargs = await self.get_tiktok_headers()
|
||
# 创建一个基础爬虫
|
||
base_crawler = BaseCrawler(proxies=kwargs["proxies"], crawler_headers=kwargs["headers"])
|
||
async with base_crawler as crawler:
|
||
# 创建一个用户点赞的BaseModel参数
|
||
params = UserLike(secUid=secUid, cursor=cursor, count=count, coverFormat=coverFormat)
|
||
# 生成一个用户点赞的带有加密参数的Endpoint
|
||
endpoint = BogusManager.model_2_endpoint(
|
||
TikTokAPIEndpoints.USER_LIKE, params.dict(), kwargs["headers"]["User-Agent"]
|
||
)
|
||
response = await crawler.fetch_get_json(endpoint)
|
||
return response
|
||
|
||
# 获取用户的收藏列表
|
||
async def fetch_user_collect(self, cookie: str, secUid: str, cursor: int = 0, count: int = 30,
|
||
coverFormat: int = 2):
|
||
# 获取TikTok的实时Cookie
|
||
kwargs = await self.get_tiktok_headers()
|
||
kwargs["headers"]["Cookie"] = cookie
|
||
# 创建一个基础爬虫
|
||
base_crawler = BaseCrawler(proxies=kwargs["proxies"], crawler_headers=kwargs["headers"])
|
||
async with base_crawler as crawler:
|
||
# 创建一个用户收藏的BaseModel参数
|
||
params = UserCollect(cookie=cookie, secUid=secUid, cursor=cursor, count=count, coverFormat=coverFormat)
|
||
# 生成一个用户收藏的带有加密参数的Endpoint
|
||
endpoint = BogusManager.model_2_endpoint(
|
||
TikTokAPIEndpoints.USER_COLLECT, params.dict(), kwargs["headers"]["User-Agent"]
|
||
)
|
||
response = await crawler.fetch_get_json(endpoint)
|
||
return response
|
||
|
||
# 获取用户的播放列表
|
||
async def fetch_user_play_list(self, secUid: str, cursor: int = 0, count: int = 30):
|
||
# 获取TikTok的实时Cookie
|
||
kwargs = await self.get_tiktok_headers()
|
||
# 创建一个基础爬虫
|
||
base_crawler = BaseCrawler(proxies=kwargs["proxies"], crawler_headers=kwargs["headers"])
|
||
async with base_crawler as crawler:
|
||
# 创建一个用户播放列表的BaseModel参数
|
||
params = UserPlayList(secUid=secUid, cursor=cursor, count=count)
|
||
# 生成一个用户播放列表的带有加密参数的Endpoint
|
||
endpoint = BogusManager.model_2_endpoint(
|
||
TikTokAPIEndpoints.USER_PLAY_LIST, params.dict(), kwargs["headers"]["User-Agent"]
|
||
)
|
||
response = await crawler.fetch_get_json(endpoint)
|
||
return response
|
||
|
||
# 获取用户的合辑列表
|
||
async def fetch_user_mix(self, mixId: str, cursor: int = 0, count: int = 30):
|
||
# 获取TikTok的实时Cookie
|
||
kwargs = await self.get_tiktok_headers()
|
||
# 创建一个基础爬虫
|
||
base_crawler = BaseCrawler(proxies=kwargs["proxies"], crawler_headers=kwargs["headers"])
|
||
async with base_crawler as crawler:
|
||
# 创建一个用户合辑的BaseModel参数
|
||
params = UserMix(mixId=mixId, cursor=cursor, count=count)
|
||
# 生成一个用户合辑的带有加密参数的Endpoint
|
||
endpoint = BogusManager.model_2_endpoint(
|
||
TikTokAPIEndpoints.USER_MIX, params.dict(), kwargs["headers"]["User-Agent"]
|
||
)
|
||
response = await crawler.fetch_get_json(endpoint)
|
||
return response
|
||
|
||
# 获取作品的评论列表
|
||
async def fetch_post_comment(self, aweme_id: str, cursor: int = 0, count: int = 20, current_region: str = ""):
|
||
# 获取TikTok的实时Cookie
|
||
kwargs = await self.get_tiktok_headers()
|
||
# proxies = {"http://": 'http://43.159.18.174:25263', "https://": 'http://43.159.18.174:25263'}
|
||
# 创建一个基础爬虫
|
||
base_crawler = BaseCrawler(proxies=None, crawler_headers=kwargs["headers"])
|
||
async with base_crawler as crawler:
|
||
# 创建一个作品评论的BaseModel参数
|
||
params = PostComment(aweme_id=aweme_id, cursor=cursor, count=count, current_region=current_region)
|
||
# 生成一个作品评论的带有加密参数的Endpoint
|
||
endpoint = BogusManager.model_2_endpoint(
|
||
TikTokAPIEndpoints.POST_COMMENT, params.dict(), kwargs["headers"]["User-Agent"]
|
||
)
|
||
response = await crawler.fetch_get_json(endpoint)
|
||
return response
|
||
|
||
# 获取作品的评论回复列表
|
||
async def fetch_post_comment_reply(self, item_id: str, comment_id: str, cursor: int = 0, count: int = 20,
|
||
current_region: str = ""):
|
||
# 获取TikTok的实时Cookie
|
||
kwargs = await self.get_tiktok_headers()
|
||
# 创建一个基础爬虫
|
||
base_crawler = BaseCrawler(proxies=kwargs["proxies"], crawler_headers=kwargs["headers"])
|
||
async with base_crawler as crawler:
|
||
# 创建一个作品评论的BaseModel参数
|
||
params = PostCommentReply(item_id=item_id, comment_id=comment_id, cursor=cursor, count=count,
|
||
current_region=current_region)
|
||
# 生成一个作品评论的带有加密参数的Endpoint
|
||
endpoint = BogusManager.model_2_endpoint(
|
||
TikTokAPIEndpoints.POST_COMMENT_REPLY, params.dict(), kwargs["headers"]["User-Agent"]
|
||
)
|
||
response = await crawler.fetch_get_json(endpoint)
|
||
return response
|
||
|
||
# 获取用户的粉丝列表
|
||
async def fetch_user_fans(self, secUid: str, count: int = 30, maxCursor: int = 0, minCursor: int = 0):
|
||
# 获取TikTok的实时Cookie
|
||
kwargs = await self.get_tiktok_headers()
|
||
# 创建一个基础爬虫
|
||
base_crawler = BaseCrawler(proxies=kwargs["proxies"], crawler_headers=kwargs["headers"])
|
||
async with base_crawler as crawler:
|
||
# 创建一个用户关注的BaseModel参数
|
||
params = UserFans(secUid=secUid, count=count, maxCursor=maxCursor, minCursor=minCursor)
|
||
# 生成一个用户关注的带有加密参数的Endpoint
|
||
endpoint = BogusManager.model_2_endpoint(
|
||
TikTokAPIEndpoints.USER_FANS, params.dict(), kwargs["headers"]["User-Agent"]
|
||
)
|
||
response = await crawler.fetch_get_json(endpoint)
|
||
return response
|
||
|
||
# 获取用户的关注列表
|
||
async def fetch_user_follow(self, secUid: str, count: int = 30, maxCursor: int = 0, minCursor: int = 0):
|
||
# 获取TikTok的实时Cookie
|
||
kwargs = await self.get_tiktok_headers()
|
||
# 创建一个基础爬虫
|
||
base_crawler = BaseCrawler(proxies=kwargs["proxies"], crawler_headers=kwargs["headers"])
|
||
async with base_crawler as crawler:
|
||
# 创建一个用户关注的BaseModel参数
|
||
params = UserFollow(secUid=secUid, count=count, maxCursor=maxCursor, minCursor=minCursor)
|
||
# 生成一个用户关注的带有加密参数的Endpoint
|
||
endpoint = BogusManager.model_2_endpoint(
|
||
TikTokAPIEndpoints.USER_FOLLOW, params.dict(), kwargs["headers"]["User-Agent"]
|
||
)
|
||
response = await crawler.fetch_get_json(endpoint)
|
||
return response
|
||
|
||
"""-------------------------------------------------------utils接口列表-------------------------------------------------------"""
|
||
|
||
# 生成真实msToken
|
||
async def fetch_real_msToken(self):
|
||
result = {
|
||
"msToken": TokenManager().gen_real_msToken()
|
||
}
|
||
return result
|
||
|
||
# 生成ttwid
|
||
async def gen_ttwid(self, cookie: str):
|
||
result = {
|
||
"ttwid": TokenManager().gen_ttwid(cookie)
|
||
}
|
||
return result
|
||
|
||
# 生成xbogus
|
||
async def gen_xbogus(self, url: str, user_agent: str):
|
||
url = BogusManager.xb_str_2_endpoint(user_agent, url)
|
||
result = {
|
||
"url": url,
|
||
"x_bogus": url.split("&X-Bogus=")[1],
|
||
"user_agent": user_agent
|
||
}
|
||
return result
|
||
|
||
# 提取单个用户id
|
||
async def get_sec_user_id(self, url: str):
|
||
return await SecUserIdFetcher.get_secuid(url)
|
||
|
||
# 提取列表用户id
|
||
async def get_all_sec_user_id(self, urls: list):
|
||
# 提取有效URL
|
||
urls = extract_valid_urls(urls)
|
||
|
||
# 对于URL列表
|
||
return await SecUserIdFetcher.get_all_secuid(urls)
|
||
|
||
# 提取单个作品id
|
||
async def get_aweme_id(self, url: str):
|
||
return await AwemeIdFetcher.get_aweme_id(url)
|
||
|
||
# 提取列表作品id
|
||
async def get_all_aweme_id(self, urls: list):
|
||
# 提取有效URL
|
||
urls = extract_valid_urls(urls)
|
||
|
||
# 对于URL列表
|
||
return await AwemeIdFetcher.get_all_aweme_id(urls)
|
||
|
||
# 获取用户unique_id
|
||
async def get_unique_id(self, url: str):
|
||
return await SecUserIdFetcher.get_uniqueid(url)
|
||
|
||
# 获取列表unique_id列表
|
||
async def get_all_unique_id(self, urls: list):
|
||
# 提取有效URL
|
||
urls = extract_valid_urls(urls)
|
||
|
||
# 对于URL列表
|
||
return await SecUserIdFetcher.get_all_uniqueid(urls)
|
||
|
||
"""-------------------------------------------------------main接口列表-------------------------------------------------------"""
|
||
|
||
async def main(self):
|
||
# 获取单个作品数据
|
||
# item_id = "7339393672959757570"
|
||
# response = await self.fetch_one_video(item_id)
|
||
# print(response)
|
||
|
||
# 获取用户的个人信息
|
||
# secUid = "MS4wLjABAAAAfDPs6wbpBcMMb85xkvDGdyyyVAUS2YoVCT9P6WQ1bpuwEuPhL9eFtTmGvxw1lT2C"
|
||
# uniqueId = "c4shjaz"
|
||
# response = await self.fetch_user_profile(secUid, uniqueId)
|
||
# print(response)
|
||
|
||
# 获取用户的作品列表
|
||
# secUid = "MS4wLjABAAAAfDPs6wbpBcMMb85xkvDGdyyyVAUS2YoVCT9P6WQ1bpuwEuPhL9eFtTmGvxw1lT2C"
|
||
# cursor = 0
|
||
# count = 35
|
||
# coverFormat = 2
|
||
# response = await self.fetch_user_post(secUid, cursor, count, coverFormat)
|
||
# print(response)
|
||
|
||
# 获取用户的点赞列表
|
||
# secUid = "MS4wLjABAAAAq1iRXNduFZpY301UkVpJ1eQT60_NiWS9QQSeNqmNQEDJp0pOF8cpleNEdiJx5_IU"
|
||
# cursor = 0
|
||
# count = 30
|
||
# coverFormat = 2
|
||
# response = await self.fetch_user_like(secUid, cursor, count, coverFormat)
|
||
# print(response)
|
||
|
||
# 获取用户的收藏列表
|
||
# cookie = "ttwid=1%7Cbf2dxDZQ2bEXkDZCxVuIuo_p3DnLZydqkW-M-yEHrQ8%7C1712658199%7C4163e4b82a08fd8160ec7d3959a3c07b2dea47b1184fd4e35619ba732a48c1f7; tt_chain_token=AlPMTLvrUZOd3f21B8dbGQ==; tiktok_webapp_theme=light; odin_tt=70b04a203cd043dbe532561dd854ce106b9c0253acf3c105969313c9f58b97bafd88ba18dd551651e4a4bf92d02067b281ca82d4a75acb17b95d7d39103aa4da0f3597fe75e56404891f651147b9bc3f; passport_csrf_token=fd79484bbdda182d711ad15fa11c059d; passport_csrf_token_default=fd79484bbdda182d711ad15fa11c059d; multi_sids=7262344915936658478%3Aa5b1dc5805dee79797d4470ffa822e45; cmpl_token=AgQQAPNSF-RO0rT35p6-9h0X_5yvjXFav6jZYNCqgQ; sid_guard=a5b1dc5805dee79797d4470ffa822e45%7C1711264624%7C15552000%7CFri%2C+20-Sep-2024+07%3A17%3A04+GMT; uid_tt=59c2975ea05dc11e9f7f548a658d65348935cb555d188c432fe2e5d0bd6b75e1; uid_tt_ss=59c2975ea05dc11e9f7f548a658d65348935cb555d188c432fe2e5d0bd6b75e1; sid_tt=a5b1dc5805dee79797d4470ffa822e45; sessionid=a5b1dc5805dee79797d4470ffa822e45; sessionid_ss=a5b1dc5805dee79797d4470ffa822e45; sid_ucp_v1=1.0.0-KDNkZDkzMWRkNzMwOTU4NWVjZWNjZDAxZGE0NDgyNDJlYWQ3MTU4YjcKIAiuiJO2k4fC5GQQ8Kb_rwYYswsgDDDCkaSmBjgBQOoHEAQaB3VzZWFzdDUiIGE1YjFkYzU4MDVkZWU3OTc5N2Q0NDcwZmZhODIyZTQ1; ssid_ucp_v1=1.0.0-KDNkZDkzMWRkNzMwOTU4NWVjZWNjZDAxZGE0NDgyNDJlYWQ3MTU4YjcKIAiuiJO2k4fC5GQQ8Kb_rwYYswsgDDDCkaSmBjgBQOoHEAQaB3VzZWFzdDUiIGE1YjFkYzU4MDVkZWU3OTc5N2Q0NDcwZmZhODIyZTQ1; store-idc=useast5; store-country-code=us; store-country-code-src=uid; tt-target-idc=useast5; tt-target-idc-sign=hG594kSqj5ODjFKxKHu5O7_f0V5snMn-pNH9xbtYUWPjnSrq6LBUTwNfeMfgVdLAPiOuLNMMg5XQw54qK0h3--UlLvHwwkLKKvtGRPKb0PV3sJSg_M6EAAMDXHVz8dYwteofNu4j7ojwk10lEmZpuzXaAT574unoAu3gk-gJV9DlFkw-kwD_rHOkelP6Lk0Gw1fGDY3Om20-0tVFVJ8mmEOZtjkxnwgZ8-Eo707aT1lGidJ8PZKIbNkgo3udCLpy3rSl-LuUsYiPOfTwg1Ih7nv4Y2OeBOG5w21c9_6Yeo9SGcjf2gtuwQASkjWDy1vLxipf0cYrfFhVlOk2xgZi-RgbhQg62kiYSUe-Mv0zgmYPTTPXMz9okU3Y3IEklz-2adsaZY5kW8qJRBYp1yUhXPr5e7rf04Clj453VxYO5urfI935gMyB8p1KXpJrSaO3OLyZ2YKyNLnEGXBCMBbDzCOrMj8guP42JPOuf-fTIJkYhfHpqqTBHj3h7st22jY3; last_login_method=email; msToken=uhdWmwVzRuGO6X5Qzob8gV2OmXcf6t0FAQeHHIQAx__ZNZubBNAbfK3W7T-E4EN8_OfagmkDu_qAwo6MSaq-qhtPel9tndR7ZaNzoIhsyueXfEYtl8AfTxR9JZk5UemPY7GQ; tt_csrf_token=kOLsNXq3-r4m3r3K1YME0Ga961eYwydSITsM; ak_bmsc=A665D13C6586D765DDF447442952896E~000000000000000000000000000000~YAAQyuIsF15v8sCOAQAAKNIGwhcV5kjZ/zGNalPWSyQXieZLY9SKy2VxEzWDzgy/YRSQLTVBC9WBFE+RXuayfyihX1Rbsm+DQ4sTtTzHIUY20Yu1tWQjcakcvZXtfLp7I0q6fcP9ai53N1iG5wwovNyFJ1eyMQVLm650J2PK59+7DcZn3kmOAHjMl6plVx6mVRoTqXcRte4b5JDtORNbXAbjSgbQiJK5fpJPSFKd19j3C/7hJij3mFvcVMa7hlBIDYlDAshlyrykE/MaoRof0RRZCNuJfO45ZdftS5+YYhuLZXbUsaJXsj3DjmaZj90kNyhovKh4AepeXm6FeC2Mejp4nCILsF0c9nZmTl2jh+TerAffOmdwieV2UejJgfAIcSXrZ1dVWtu0dQ==; passport_fe_beating_status=true; perf_feed_cache={%22expireTimestamp%22:1712822400000%2C%22itemIds%22:[%227351502927267171630%22%2C%227349225060231679275%22%2C%227351880657787800864%22]}; bm_sv=0B6DC970D9D01727EB672641008F9C9D~YAAQxeIsFy0Bw5iOAQAAOChiwhecEatJ7PnT5D7Z1Cr2pcpz/MkHKvKSfCtcnD+888hhDkzPART3agFPgqxJzjotbMOL9vMYCaF331W/Ahjx+/L9pVnvOqKVyhwYw58LJG1NgB2tliqi18Exun04pomLtD195iDMfNbGdYmGt7WrtWumTuI7qEjkR4QAClrPNP1JFYUGT9A29+iGzc+/wqDZiG+0AGXUlTEBmIKM398S9DqSWpJrRvNODjMe7Fg2~1; _waftokenid=eyJ2Ijp7ImEiOiJweEtDTWVrOENLZEZyMDY5bzE1T01KL2RncVNSVWlzZ0xtQVAyZXJDeWw0PSIsImIiOjE3MTI2NTgxMjYsImMiOiJJTU94cGtQS1FuSG1XbVNOYUx0Yk5ldndQR2w5RkxIbkJXaEExOTVPbzFZPSJ9LCJzIjoiL3JDZDl1dXVIWkRvSTc2M1dLM2VHR2hNQU9vbGJGKy9oMFdtTXE3Zkgwaz0ifQ; msToken=J4gOwTXU0OEU6MH3VjhUVmCYMNGqtznsRSDxyl8KNlfSTPM7fMYYXHPPIpldHRFUx_fPfyhVclvrX6WnrNdxk3GzK_7BHmhIIkQbQ1zSSnqY2Phn6QduvErSGvCQyvxwTctWzslT3BqiIg=="
|
||
# secUid = "MS4wLjABAAAAq1iRXNduFZpY301UkVpJ1eQT60_NiWS9QQSeNqmNQEDJp0pOF8cpleNEdiJx5_IU"
|
||
# cursor = 0
|
||
# count = 30
|
||
# coverFormat = 2
|
||
# response = await self.fetch_user_collect(cookie, secUid, cursor, count, coverFormat)
|
||
# print(response)
|
||
|
||
# 获取用户的播放列表
|
||
# secUid = "MS4wLjABAAAAtGboV-mJHSIQqh-SsG30QKweGhSqkr4xJLq1qqgAWDzu3vDO5LUhUcCP4UEY5LwC"
|
||
# cursor = 0
|
||
# count = 30
|
||
# response = await self.fetch_user_play_list(secUid, cursor, count)
|
||
# print(response)
|
||
|
||
# 获取用户的合辑列表
|
||
# mixId = "7101538765474106158"
|
||
# cursor = 0
|
||
# count = 30
|
||
# response = await self.fetch_user_mix(mixId, cursor, count)
|
||
# print(response)
|
||
|
||
# 获取作品的评论列表
|
||
# aweme_id = "7304809083817774382"
|
||
# cursor = 0
|
||
# count = 20
|
||
# current_region = ""
|
||
# response = await self.fetch_post_comment(aweme_id, cursor, count, current_region)
|
||
# print(response)
|
||
|
||
# 获取作品的评论回复列表
|
||
# item_id = "7304809083817774382"
|
||
# comment_id = "7304877760886588191"
|
||
# cursor = 0
|
||
# count = 20
|
||
# current_region = ""
|
||
# response = await self.fetch_post_comment_reply(item_id, comment_id, cursor, count, current_region)
|
||
# print(response)
|
||
|
||
# 获取用户的关注列表
|
||
# secUid = "MS4wLjABAAAAtGboV-mJHSIQqh-SsG30QKweGhSqkr4xJLq1qqgAWDzu3vDO5LUhUcCP4UEY5LwC"
|
||
# count = 30
|
||
# maxCursor = 0
|
||
# minCursor = 0
|
||
# response = await self.fetch_user_follow(secUid, count, maxCursor, minCursor)
|
||
# print(response)
|
||
|
||
# 获取用户的粉丝列表
|
||
# secUid = "MS4wLjABAAAAtGboV-mJHSIQqh-SsG30QKweGhSqkr4xJLq1qqgAWDzu3vDO5LUhUcCP4UEY5LwC"
|
||
# count = 30
|
||
# maxCursor = 0
|
||
# minCursor = 0
|
||
# response = await self.fetch_user_fans(secUid, count, maxCursor, minCursor)
|
||
# print(response)
|
||
|
||
"""-------------------------------------------------------utils接口列表-------------------------------------------------------"""
|
||
|
||
# # 生成真实msToken
|
||
# response = await self.fetch_real_msToken()
|
||
# print(response)
|
||
|
||
# 生成ttwid
|
||
# cookie = "ttwid=1%7Cbf2dxDZQ2bEXkDZCxVuIuo_p3DnLZydqkW-M-yEHrQ8%7C1712664278%7C6ed45f1bb91c86eda1e08c6f60da7898591ed368ee7feece0a78f48d6e734d71; tt_chain_token=AlPMTLvrUZOd3f21B8dbGQ==; tiktok_webapp_theme=light; odin_tt=dada47a81f211d932ae6c5a0dc99b4e87029d27b49b0fc4a83faf6bc91bebddcf3665c25f1a7c0934dc27c89ab2a7151e116cc22110c24b927051de11b54c3e66e6567dba55e88d2f92f52a7b857d27f; passport_csrf_token=fd79484bbdda182d711ad15fa11c059d; passport_csrf_token_default=fd79484bbdda182d711ad15fa11c059d; multi_sids=7262344915936658478%3Aa5b1dc5805dee79797d4470ffa822e45; cmpl_token=AgQQAPNSF-RO0rT35p6-9h0X_5yvjXFav6jZYNCqgQ; sid_guard=a5b1dc5805dee79797d4470ffa822e45%7C1711264624%7C15552000%7CFri%2C+20-Sep-2024+07%3A17%3A04+GMT; uid_tt=59c2975ea05dc11e9f7f548a658d65348935cb555d188c432fe2e5d0bd6b75e1; uid_tt_ss=59c2975ea05dc11e9f7f548a658d65348935cb555d188c432fe2e5d0bd6b75e1; sid_tt=a5b1dc5805dee79797d4470ffa822e45; sessionid=a5b1dc5805dee79797d4470ffa822e45; sessionid_ss=a5b1dc5805dee79797d4470ffa822e45; sid_ucp_v1=1.0.0-KDNkZDkzMWRkNzMwOTU4NWVjZWNjZDAxZGE0NDgyNDJlYWQ3MTU4YjcKIAiuiJO2k4fC5GQQ8Kb_rwYYswsgDDDCkaSmBjgBQOoHEAQaB3VzZWFzdDUiIGE1YjFkYzU4MDVkZWU3OTc5N2Q0NDcwZmZhODIyZTQ1; ssid_ucp_v1=1.0.0-KDNkZDkzMWRkNzMwOTU4NWVjZWNjZDAxZGE0NDgyNDJlYWQ3MTU4YjcKIAiuiJO2k4fC5GQQ8Kb_rwYYswsgDDDCkaSmBjgBQOoHEAQaB3VzZWFzdDUiIGE1YjFkYzU4MDVkZWU3OTc5N2Q0NDcwZmZhODIyZTQ1; store-idc=useast5; store-country-code=us; store-country-code-src=uid; tt-target-idc=useast5; tt-target-idc-sign=hG594kSqj5ODjFKxKHu5O7_f0V5snMn-pNH9xbtYUWPjnSrq6LBUTwNfeMfgVdLAPiOuLNMMg5XQw54qK0h3--UlLvHwwkLKKvtGRPKb0PV3sJSg_M6EAAMDXHVz8dYwteofNu4j7ojwk10lEmZpuzXaAT574unoAu3gk-gJV9DlFkw-kwD_rHOkelP6Lk0Gw1fGDY3Om20-0tVFVJ8mmEOZtjkxnwgZ8-Eo707aT1lGidJ8PZKIbNkgo3udCLpy3rSl-LuUsYiPOfTwg1Ih7nv4Y2OeBOG5w21c9_6Yeo9SGcjf2gtuwQASkjWDy1vLxipf0cYrfFhVlOk2xgZi-RgbhQg62kiYSUe-Mv0zgmYPTTPXMz9okU3Y3IEklz-2adsaZY5kW8qJRBYp1yUhXPr5e7rf04Clj453VxYO5urfI935gMyB8p1KXpJrSaO3OLyZ2YKyNLnEGXBCMBbDzCOrMj8guP42JPOuf-fTIJkYhfHpqqTBHj3h7st22jY3; last_login_method=email; msToken=t3WAFkKaIqii9eMTPHdks49bnQnrcb-qA8i0K6CbTF-2MBdObKnGfU3icz53Wot781BQXPL4PT4ZI2nIFacyECthXfFPg6JrkghC_Yn7pf6aut5YU7PpqeuAa3Ipg-1OAYS2rF3UrQOetw==; tt_csrf_token=kOLsNXq3-r4m3r3K1YME0Ga961eYwydSITsM; passport_fe_beating_status=true; ak_bmsc=24B67BCA11EE8356DD40E4F7E23FC910~000000000000000000000000000000~YAAQyOIsF//Uz6COAQAAe/5/whdqkLc0AH5d8i2rlJjtjjMuK1K+tU3kWANu/7PWSoOfbjdVZi9uFRKsuQj1DU0Ztew9uihAT+jWEvqNo1cbee/FRwJLMZk80po2nI/GwpLKd51dHN5HW7dWc58oeWwpIOh/g2uVkXJjtVotM4sBcEYxO1i9fpOF0bgOOVXrElmpqaFVfWBJc0iBBHHBZEAHNSIGHjPHY7j+Gy4YMoldkJKJbMVtRWa3ChfagC7vgWsiy2sb3lDGRbSQgjYj128i2lwoPtbcA3bzLZPd6jseTgRHm01arjyMJh3RrhDUyu71D1jMPuWhVkAjAV21vrsJFmgFWQ3Ryv23yDa6kSq7qRBLQAxA6rYcYBRNPdoNOAaiLt5IBCHiWQ==; bm_sv=FB0D8C84058596C33C95C34477181900~YAAQ3+IsF1bJy52OAQAAIOy+whed7uxWbcSbX9ww9mH0hyPTbQLecKO8qrRli6xSOco/iX7wxO9RXW6ikifIc2RFIbvzAZg3j58QNuEJ5hXrIia0yc0T/j1cCjhqBypDWXc6KaC716f293K5lbOFoD7QMFCA3K4YsMK3mJa2KaBzOvwOTdbpmow8PM0fKAXwSxJDPweGCzxZhiMNC+H/TFscBYb5HdDZ7PkuiN97YPtVEtfMd4WcpHos3e5dFJS+~1; living_user_id=743289106087; csrfToken=ndffXer7-a5_J5Me7ffRmSSJfzfMDmX3B6oM; perf_feed_cache={%22expireTimestamp%22:1712836800000%2C%22itemIds%22:[%227348432053190380842%22%2C%227352682225256762666%22%2C%227350485674086157611%22]}; csrf_session_id=120d8aacffb06addd01cb40859003c8e; msToken=8tbUEEpe8rNjEkOrH6M5v-RXjSUaCAARr-Knyk11POdQHvjVvQjbXEbEP4vcAf2ftbB7ycHOz7LlQbADkPURuVvseAstrFbSmxY3uVJOLAgS6O9h3BnXmpHH_kPw4xXgF2zDv4E-U58JZw=="
|
||
# response = await self.gen_ttwid(cookie)
|
||
# print(response)
|
||
|
||
# 生成xbogus
|
||
# url = "https://www.tiktok.com/api/item/detail/?WebIdLastTime=1712665533&aid=1988&app_language=en&app_name=tiktok_web&browser_language=en-US&browser_name=Mozilla&browser_online=true&browser_platform=Win32&browser_version=5.0%20%28Windows%29&channel=tiktok_web&cookie_enabled=true&device_id=7349090360347690538&device_platform=web_pc&focus_state=true&from_page=user&history_len=4&is_fullscreen=false&is_page_visible=true&language=en&os=windows&priority_region=US&referer=®ion=US&root_referer=https%3A%2F%2Fwww.tiktok.com%2F&screen_height=1080&screen_width=1920&webcast_language=en&tz_name=America%2FTijuana&msToken=AYFCEapCLbMrS8uTLBoYdUMeeVLbCdFQ_QF_-OcjzJw1CPr4JQhWUtagy0k4a9IITAqi5Qxr2Vdh9mgCbyGxTnvWLa4ZVY6IiSf6lcST-tr0IXfl-r_ZTpzvWDoQfqOVsWCTlSNkhAwB-tap5g==&itemId=7339393672959757570"
|
||
# user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"
|
||
# response = await self.gen_xbogus(url, user_agent)
|
||
# print(response)
|
||
|
||
# 提取单个用户secUid
|
||
# url = "https://www.tiktok.com/@tiktok"
|
||
# response = await self.get_sec_user_id(url)
|
||
# print(response)
|
||
|
||
# 提取多个用户secUid
|
||
# urls = ["https://www.tiktok.com/@tiktok", "https://www.tiktok.com/@taylorswift"]
|
||
# response = await self.get_all_sec_user_id(urls)
|
||
# print(response)
|
||
|
||
# 提取单个作品id
|
||
# url = "https://www.tiktok.com/@taylorswift/video/7162153915952352558"
|
||
# response = await self.get_aweme_id(url)
|
||
# print(response)
|
||
|
||
# 提取多个作品id
|
||
# urls = ["https://www.tiktok.com/@taylorswift/video/7162153915952352558", "https://www.tiktok.com/@taylorswift/video/7137077445680745771"]
|
||
# response = await self.get_all_aweme_id(urls)
|
||
# print(response)
|
||
|
||
# 获取用户unique_id
|
||
# url = "https://www.tiktok.com/@tiktok"
|
||
# response = await self.get_unique_id(url)
|
||
# print(response)
|
||
|
||
# 获取多个用户unique_id
|
||
# urls = ["https://www.tiktok.com/@tiktok", "https://www.tiktok.com/@taylorswift"]
|
||
# response = await self.get_all_unique_id(urls)
|
||
# print(response)
|
||
|
||
# 占位
|
||
pass
|
||
|
||
|
||
if __name__ == "__main__":
|
||
# 初始化
|
||
TikTokWebCrawler = TikTokWebCrawler()
|
||
|
||
# 开始时间
|
||
start = time.time()
|
||
|
||
asyncio.run(TikTokWebCrawler.main())
|
||
|
||
# 结束时间
|
||
end = time.time()
|
||
print(f"耗时:{end - start}")
|