初始化仓库
This commit is contained in:
273
src/assets/img/demos/2025-04/tiktokAPI(2).py
Normal file
273
src/assets/img/demos/2025-04/tiktokAPI(2).py
Normal file
@@ -0,0 +1,273 @@
|
||||
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))
|
||||
|
||||
# 获取x,y的坐标
|
||||
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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user