Commit fb663d1b by Peng

no message

parent a8e938f4
......@@ -102,6 +102,9 @@ class TkVideo():
'xpath://div[.//*[contains(text(),"Upgrade your account")]]//button[.//svg][1]',
# 新增:通用兜底,任何 dialog 的右上角第一个无文字 svg 按钮
'xpath:(//div[@role="dialog"]//button[.//svg and not(.//span)])[1]',
# —— 新增:TikTok "商业工具已解锁" 弹窗 ——
'xpath://button[.//div[text()="开始使用"]]',
'xpath://button[.//div[text()="Get started"]]',
]
for xp in candidates:
try:
......@@ -124,6 +127,14 @@ class TkVideo():
time.sleep(2)
self.dismiss_popups() # 二次复查,覆盖延迟出现的"升级你的账号"弹窗
# 如果弹窗导致页面跳转,重新回到视频数据页
if 'insight/video' not in self.page_chrome.url:
print('⚠️ 弹窗导致页面跳转,重新回到视频数据页')
self.page_chrome.get("https://www.tiktok.com/business-suite/insight/video")
time.sleep(random.randint(6, 10))
self.dismiss_popups()
time.sleep(2)
export_orders = self.page_chrome.ele('xpath://span[text()="自定义"]', timeout=13)
export_orders.click()
print('点击自定义')
......@@ -192,15 +203,66 @@ class TkVideo():
timeout=15
).text
print(f'已获取店铺名: {self.shop_name}')
self.key = self.page_chrome.ele(
'xpath://img[contains(@class,"rounded-full")]/following-sibling::div//div[contains(@class,"text-P3-Regular") and contains(@class,"text-color-TextSecondary")]',
timeout=15
).text.lstrip('@')
self.key = self._get_account_key(self.page_chrome)
print(f'已获取账号用户名: {self.key}')
sleep(randint(5, 10))
self.save_to_redis()
time.sleep(5)
def _get_account_key(self, page):
"""多策略获取TikTok账号用户名,带交叉验证"""
results = {}
# 策略1: class XPath
try:
val = page.ele(
'xpath://img[contains(@class,"rounded-full")]/following-sibling::div'
'//div[contains(@class,"text-P3-Regular") and contains(@class,"text-color-TextSecondary")]',
timeout=10
).text.strip()
if val.startswith('@') and len(val) > 1:
results['class_xpath'] = val.lstrip('@')
else:
print(f' [策略1] 命中元素但内容非用户名: [{val}]')
except Exception as e:
print(f' [策略1] class XPath 失败: {e}')
# 策略2: 头像容器内找 @ 开头文本
try:
val = page.ele(
'xpath://img[contains(@class,"rounded-full")]/parent::div//*[starts-with(text(),"@")]',
timeout=10
).text.strip()
if val.startswith('@') and len(val) > 1:
results['at_prefix'] = val.lstrip('@')
except Exception as e:
print(f' [策略2] @ 前缀搜索失败: {e}')
# 策略3: "粉丝" 文字反向定位同行第一个 div
try:
val = page.ele(
'xpath://span[text()="粉丝"]/parent::div/parent::div/div[1]',
timeout=5
).text.strip()
if val.startswith('@') and len(val) > 1:
results['fans_anchor'] = val.lstrip('@')
except Exception as e:
print(f' [策略3] 粉丝锚点失败: {e}')
if not results:
raise Exception('所有策略均无法获取账号用户名,TikTok页面可能改版')
unique = set(results.values())
if len(unique) == 1:
key = unique.pop()
print(f' [校验通过] {len(results)}个策略一致: {list(results.keys())}')
return key
print(f' [校验警告] 策略结果不一致: {results}')
if 'at_prefix' in results:
return results['at_prefix']
return list(results.values())[0]
def connect_redis(self):
"""建立 Redis 连接"""
self.r = redis.StrictRedis(**self.REDIS_CONFIG)
......@@ -227,8 +289,7 @@ class TkVideo():
'添加到收藏': 'favorites'
}
# 强制所有列为字符串类型,防止科学计数法
df = pd.read_excel(file_path, dtype=str)
df = pd.read_excel(file_path)
# 替换列名为英文
df.rename(columns=column_mapping, inplace=True)
......@@ -337,13 +398,15 @@ class TkVideo():
print('删除数据失败')
def send_error_notification_via_wechat(self,error_message):
webhook_url = 'http://47.112.96.71:8082/selection/sendMessage' # 替换为你的企业微信机器人的Webhook URL
self.receiver_name = 'pengyanbing,zouliqing'
host = "http://120.79.147.190:8080"
webhook_url = f'{host}/soundasia_selection/dolphinScheduler/sendMessage'
data = {
"account": self.receiver_name,
'title':'【TK视频数据下载异常提醒】',
'content':f'账号:{self.key},错误信息:{error_message}, 时间: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}'
'account': self.receiver_name,
'title': '【TK视频数据下载异常提醒】',
'content': f'账号:{self.key},错误信息:{error_message}, 时间: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}',
'msgtype': 'textcard'
}
response = requests.post(url=webhook_url, data=data,timeout=15)
if response.status_code == 200:
print("已成功发送错误通知到企业微信")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment