Files
yoloHome/src/assets/img/demos/2025-04/tiktokAPI(2).py
2025-07-01 21:14:03 +08:00

274 lines
11 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import base64
import time
import requests
from DrissionPage import ChromiumPage
from DrissionPage import ChromiumOptions
from PIL import Image,ImageDraw
import random
from DrissionPage.common import Actions
class batch_check_anchor:
def __init__(self,username,password, callback):
# 在初始化时进行一系列的自动化操作,登录->关闭窗口->点击邀约主播
start_time=time.time()
false=False
true=True
co = ChromiumOptions()
# co.incognito()
# 设置不加载图片、静音
co.mute(True)
co.headless(False)
co.auto_port(True)
self.page = ChromiumPage(co)
self.page.set.window.max()
#self.page.set.cookies.clear()
self.page.get('https://live-backstage.tiktok.com/portal/overview')
loginele=self.page.ele("@data-id=login")
cookie = self.page.ele("全部允许")
if cookie:
p = self.page.ele('@user-config-ele-id=tiktok-cookie-banner-config').shadow_root
b = p.eles('tag:button')
if b:
b[-1].click()
if loginele:
#
# self.page.set.window.show()
# 点击登录按钮
self.page.ele("@data-id=login").click()
time.sleep(random.random())
# 输入账号
self.page.ele("@class=semi-input semi-input-default").input(username,clear=True)
time.sleep(random.random())
# 输入密码
self.page.ele("@class=semi-input semi-input-default semi-input-sibling-modebtn").input(password,clear=True)
# 点击进行登录
time.sleep(random.random())
self.page.ele("@data-id=login-primary-button").click()
while True:
try:
loginele=self.page.ele("@data-id=login",timeout=1)
if not loginele:
print('后台登录成功')
# self.page.set.window.hide()
if callback:
callback()
break
time.sleep(0.2)
except:
pass
ele=self.page.ele('@class=semi-button semi-button-tertiary semi-button-size-small semi-button-borderless semi-modal-close semi-button-with-icon semi-button-with-icon-only')
print("3s 点击 关闭页面")
if ele:
ele.click()
page = self.page.ele("@data-id=guide-ok")
if page:
page.click()
invite_btn = self.page.ele("@class=semi-button semi-button-primary semi-button-with-icon",timeout=1)
if not invite_btn:
btn = self.page.ele("@data-id=know")
if btn:
btn.click()
check_btn = self.page.ele("@data-id=workplace-switch-button")
if check_btn:
check_btn.click()
while true:
time.sleep(0.2)
ele=self.page.ele('@data-id=add-host-btn')
try:
if ele:
ele.click()
inputele=self.page.eles('@class=semi-input-textarea semi-input-textarea-autosize')[1]
if inputele:
break
except:
ele=self.page.ele('@class=semi-button semi-button-tertiary semi-button-size-small semi-button-borderless semi-modal-close semi-button-with-icon semi-button-with-icon-only')
if ele:
ele.click()
end_time=time.time()
self.get_anchor("测试")
print('初始化完成 耗时:',end_time-start_time)
def get_ip(self):
# 提取代理API接口获取1个代理IP
api_url = "https://dps.kdlapi.com/api/getdps/?secret_id=ohs2d9r6kqdtt2tau900&signature=gktsvou9sd0nq7o09q3ridg70aal97b1&num=1&pt=1&sep=1"
# 获取API接口返回的代理IP
proxy_ip = requests.get(api_url).text
# 用户名密码认证(私密代理/独享代理)
username = "d2400186192"
password = "5yv1r337"
proxies = {
"http": "http://%(user)s:%(pwd)s@%(proxy)s/" % {"user": username, "pwd": password, "proxy": proxy_ip},
"https": "http://%(user)s:%(pwd)s@%(proxy)s/" % {"user": username, "pwd": password, "proxy": proxy_ip}
}
return proxies
# 法国 德国
# 处理tiktok的验证码
def deal_identifying_code(self,b):
url = "http://api.jfbym.com/api/YmServer/customApi"
data = {
## 关于参数,一般来说有3个;不同类型id可能有不同的参数个数和参数名,找客服获取
"token": "w7hWcZPPOgQG2WTg4os5vD2WnYZ38g9bLWnmBxGUHY4",
"type": "30101",
"image": b,
}
_headers = {
"Content-Type": "application/json"
}
response = requests.request("POST", url, headers=_headers, json=data, proxies=self.get_ip()).json()
print(response)
return response['data']['data']
# text传入邀约
def get_anchor(self,text):
start_time=time.time()
while True:
try:
inputele=self.page.eles('@class=semi-input-textarea semi-input-textarea-autosize')[1]
if inputele:
inputele.click()
inputele.input(text,clear=True)
print("点击了测试")
self.page.listen.start('https://live-backstage.tiktok.com/creators/live/union_platform_api/agency/union_invite/batch_check_anchor/')
print("监听url")
while True:
nextele=self.page.eles('@data-id=invite-host-next')[0]
if nextele:
time.sleep(0.5)
print("点击下一步")
nextele.click()
backele=self.page.ele('@data-id=invite-host-back')
if backele:
break
max_retries = 3 # 定义最大重试次数
failure_count = 0 # 初始化失败计数器
while True:
checkele=self.page.ele('@class=TUXButton-content')
if failure_count >= max_retries:
print("验证失败超过3次终止流程")
break #
if checkele:
# self.page.set.window.show()
print(f"{failure_count + 1}次尝试处理验证码")
# 发现验证码截图保存到本地
failure_count += 1
# 定位元素
element = self.page.ele(
"@class=cap-rounded-lg cap-cursor-pointer cap-w-full cap-h-auto")
# 截取该元素并保存
element.get_screenshot("tiktok_identifying_code.png")
# time.sleep(random.random())
with open('tiktok_identifying_code.png', 'rb') as f:
b = base64.b64encode(f.read()).decode() ## 图片二进制流base64字符串
# 处理验证码
result = self.deal_identifying_code(b)
print(result, type(result))
# 获取xy的坐标
a = 1
for i in result.split('|'):
a += 1
x = int(int(i.split(',')[0]) * (348 / 552))
y = int(int(i.split(',')[1]) * (217 / 344))
ac = Actions(self.page)
ac.move_to(ele_or_loc=element, offset_x=0, offset_y=0).move(x, y).click()
# print(x,y)
# img = Image.open("tiktok_identifying_code.png")
# draw = ImageDraw.Draw(img)
# draw.ellipse([(x - 5, y - 5), (x + 5, y + 5)], fill='red') # 用红圈标记点击位置
# img.save(f"marked_identifying_code{a}.png")
self.page.ele(
"@class=TUXButton TUXButton--default TUXButton--medium TUXButton--primary cap-my-8 cap-w-full").click()
back_btn = self.page.ele("@data-id=invite-host-back")
if back_btn:
back_btn.click()
continue
# else:
# break
backele=self.page.ele('@data-id=invite-host-back')
if backele:
break
# time.sleep(0.2)
print('重复点击1')
# self.page.set.window.show()
res=self.page.listen.wait(1)
self.page.listen.stop()
while True:
backele=self.page.ele('@data-id=invite-host-back')
backele.click()
nextele=self.page.eles('@data-id=invite-host-next')[0]
if nextele:
break
# time.sleep(0.2)
print('重复点击2')
# self.page.set.window.show()
break
except Exception as e:
print('报错的原因',e)
self.page.refresh()
ele=self.page.ele('@class=semi-button semi-button-tertiary semi-button-size-small semi-button-borderless semi-modal-close semi-button-with-icon semi-button-with-icon-only')
if ele:
ele.click()
else:
check_btn = self.page.ele("@data-id=workplace-switch-button")
if check_btn:
check_btn.click()
while True:
ele=self.page.ele('@data-id=add-host-btn')
try:
if ele:
ele.click()
inputele=self.page.eles('@class=semi-input-textarea semi-input-textarea-autosize')[1]
if inputele:
break
except:
ele=self.page.ele('@class=semi-button semi-button-tertiary semi-button-size-small semi-button-borderless semi-modal-close semi-button-with-icon semi-button-with-icon-only',timeout=1)
if ele:
ele.click()
end_time=time.time()
print('耗时:',end_time-start_time)
return res.response.body