hahaa
BIN
dist/gui_app.exe
vendored
BIN
gui_app.exe
3160
gui_app.py
38
gui_app.spec
@@ -1,38 +0,0 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
|
||||
a = Analysis(
|
||||
['c:\\Users\\27942\\Desktop\\haha\\gui_app.py'],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=[('c:\\Users\\27942\\Desktop\\haha\\main.py', '.')],
|
||||
hiddenimports=[],
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
noarchive=False,
|
||||
optimize=0,
|
||||
)
|
||||
pyz = PYZ(a.pure)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.datas,
|
||||
[],
|
||||
name='gui_app',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=False,
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
)
|
||||
340
main.py
@@ -272,7 +272,7 @@ class Pdd:
|
||||
print(f"下载失败: {e}")
|
||||
return None
|
||||
|
||||
def action(self, folder_path=None):
|
||||
def action(self, folder_path=None, collect_all_videos=False):
|
||||
self.create_page()
|
||||
|
||||
if datas.get(self.user_id):
|
||||
@@ -311,54 +311,196 @@ class Pdd:
|
||||
datas[self.user_id] = creator_tab.url
|
||||
|
||||
# 从文件夹读取文件
|
||||
file_paths = []
|
||||
video_file_paths = [] # 视频文件列表
|
||||
image_folder_paths = [] # 图片文件夹列表(用于存储图片文件夹路径)
|
||||
if folder_path and os.path.exists(folder_path):
|
||||
logger.info(f"开始读取文件夹: {folder_path}")
|
||||
logger.info(f"查找序号为 '{self.index}' 的文件")
|
||||
|
||||
# 支持的视频格式
|
||||
video_extensions = ['.mp4', '.avi', '.mov', '.mkv', '.flv', '.wmv', '.webm']
|
||||
# 支持的图片格式
|
||||
image_extensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp']
|
||||
|
||||
# 获取文件夹中的所有文件
|
||||
for file in os.listdir(folder_path): # 获取文件夹下所有的文件夹
|
||||
file_path = os.path.join(folder_path, file) # 拼接文件夹
|
||||
# 检查是否为目录,跳过文件(如.lnk快捷方式)
|
||||
if not os.path.isdir(file_path):
|
||||
continue
|
||||
files = os.listdir(file_path) # 获取用户id下的文件
|
||||
for file in files:
|
||||
file_names = file.split("-")
|
||||
if file_names[0] == self.index:
|
||||
path = Path(os.path.join(file_path, file))
|
||||
# 判断是否为文件
|
||||
if path.is_file():
|
||||
file_paths.append(path)
|
||||
creator_tab.ele("x://*[text()='添加视频']").click.to_upload(file_paths)
|
||||
|
||||
# xpath_path = creator_tab.ele('x://*[text()="添加视频描述"]').xpath
|
||||
# new_path = re.sub(r'div\[1\]$', 'div[2]', xpath_path)
|
||||
# new_path += "/div[2]/div/div[1]/div[2]"
|
||||
# creator_tab.ele(f'x:{new_path}').input(vals=self.title + self.ht, clear=True)
|
||||
|
||||
time.sleep(3)
|
||||
creator_tab.ele(f'x://*[@id="magicdomid1"]').input(
|
||||
vals=file_names[-1].split(".")[0] + self.ht, clear=True)
|
||||
|
||||
break
|
||||
# 第一步:先收集所有匹配的视频文件和图片文件夹
|
||||
logger.info("=" * 50)
|
||||
if collect_all_videos:
|
||||
logger.info("第一步:扫描文件夹,收集所有视频文件(批量上传模式,不限制序号)...")
|
||||
else:
|
||||
logger.info(f"第一步:扫描文件夹,收集序号为 '{self.index}' 的文件...")
|
||||
|
||||
# 获取最外层文件夹下的所有子文件夹(多多ID文件夹)
|
||||
subdirs = [f for f in os.listdir(folder_path) if os.path.isdir(os.path.join(folder_path, f))]
|
||||
logger.info(f"在最外层文件夹下找到 {len(subdirs)} 个子文件夹(多多ID文件夹)")
|
||||
|
||||
# 找到匹配当前多多ID的文件夹
|
||||
target_subdir = None
|
||||
for subdir_name in subdirs:
|
||||
if subdir_name == str(self.user_id):
|
||||
target_subdir = os.path.join(folder_path, subdir_name)
|
||||
logger.info(f"✓ 找到匹配的多多ID文件夹: {subdir_name}")
|
||||
break
|
||||
|
||||
if not target_subdir:
|
||||
logger.warning(f"未找到多多ID为 {self.user_id} 的文件夹")
|
||||
logger.info(f"可用的文件夹: {subdirs}")
|
||||
logger.error("无法继续执行,因为未找到匹配的多多ID文件夹")
|
||||
return
|
||||
else:
|
||||
# 只扫描匹配的多多ID文件夹
|
||||
logger.info(f" 正在扫描子文件夹: {os.path.basename(target_subdir)}")
|
||||
|
||||
# 获取该子文件夹下的所有文件和文件夹
|
||||
try:
|
||||
items = os.listdir(target_subdir)
|
||||
logger.info(f" 该文件夹下有 {len(items)} 个项目")
|
||||
|
||||
for item_name in items:
|
||||
item_path = os.path.join(target_subdir, item_name)
|
||||
logger.info(f" 检查项目: {item_name}")
|
||||
|
||||
# 分割文件名,检查第一部分是否匹配序号
|
||||
name_parts = item_name.split("-")
|
||||
logger.info(f" 文件名分割结果: {name_parts}")
|
||||
|
||||
# 如果是批量上传模式,收集所有视频文件;否则只收集匹配序号的文件
|
||||
should_collect = False
|
||||
if collect_all_videos:
|
||||
# 批量上传模式:只要文件名格式正确(有序号),就收集视频文件
|
||||
if len(name_parts) > 0 and name_parts[0].isdigit():
|
||||
should_collect = True
|
||||
logger.info(f" 批量上传模式:序号 {name_parts[0]} 将被收集")
|
||||
else:
|
||||
for file in os.listdir(path):
|
||||
file_paths.append(os.path.join(path, file))
|
||||
# 单个上传模式:只收集匹配当前序号的文件
|
||||
if len(name_parts) > 0 and name_parts[0] == str(self.index):
|
||||
should_collect = True
|
||||
logger.info(f" ✓ 序号匹配!序号: {name_parts[0]}, 目标序号: {self.index}")
|
||||
|
||||
if should_collect:
|
||||
path = Path(item_path)
|
||||
|
||||
# 判断是否为文件(视频文件)
|
||||
if path.is_file():
|
||||
# 检查是否为视频文件
|
||||
file_ext = path.suffix.lower()
|
||||
logger.info(f" 这是一个文件,扩展名: {file_ext}")
|
||||
|
||||
if any(file_ext == ext for ext in video_extensions):
|
||||
video_file_paths.append(path)
|
||||
logger.info(f" ✓ 添加到视频列表: {path.name}")
|
||||
logger.info(f" 当前视频总数: {len(video_file_paths)}")
|
||||
else:
|
||||
logger.info(f" ✗ 不是视频文件,跳过")
|
||||
else:
|
||||
# 这是一个图片文件夹(只在单个上传模式下处理)
|
||||
if not collect_all_videos:
|
||||
image_folder_paths.append(path)
|
||||
logger.info(f" ✓ 添加到图片文件夹列表: {path.name}")
|
||||
logger.info(f" 当前图片文件夹总数: {len(image_folder_paths)}")
|
||||
else:
|
||||
if len(name_parts) > 0:
|
||||
if collect_all_videos:
|
||||
logger.info(f" ✗ 文件名格式不正确(序号不是数字),跳过")
|
||||
else:
|
||||
logger.info(f" ✗ 序号不匹配: {name_parts[0]} != {self.index}")
|
||||
else:
|
||||
logger.info(f" ✗ 文件名格式不正确,无法提取序号")
|
||||
except Exception as e:
|
||||
logger.error(f" 扫描子文件夹 {target_subdir} 时出错: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
creator_tab.ele('x://*[text()="添加图片"]').click.to_upload(file_paths)
|
||||
logger.info("=" * 50)
|
||||
logger.info(f"文件收集完成!")
|
||||
logger.info(f" 视频文件数量: {len(video_file_paths)}")
|
||||
logger.info(f" 图片文件夹数量: {len(image_folder_paths)}")
|
||||
|
||||
if video_file_paths:
|
||||
logger.info("视频文件列表:")
|
||||
for idx, video_path in enumerate(video_file_paths, 1):
|
||||
logger.info(f" {idx}. {video_path}")
|
||||
|
||||
time.sleep(3)
|
||||
# 第二步:如果有视频文件,批量上传所有视频
|
||||
if video_file_paths:
|
||||
logger.info("=" * 50)
|
||||
logger.info(f"第二步:开始批量上传 {len(video_file_paths)} 个视频文件...")
|
||||
|
||||
# 检查是否有"支持批量上传"按钮,如果有则使用批量上传
|
||||
logger.info("查找批量上传按钮...")
|
||||
batch_upload_btn = creator_tab.ele("x://*[text()='支持批量上传']", timeout=3)
|
||||
|
||||
if batch_upload_btn:
|
||||
logger.info("✓ 找到'支持批量上传'按钮")
|
||||
if len(video_file_paths) > 1:
|
||||
logger.info(f"使用批量上传模式,准备上传 {len(video_file_paths)} 个视频")
|
||||
logger.info(f"上传文件列表: {[str(p) for p in video_file_paths]}")
|
||||
batch_upload_btn.click.to_upload(video_file_paths)
|
||||
logger.info(f"✓ 已触发批量上传,上传 {len(video_file_paths)} 个视频")
|
||||
else:
|
||||
logger.info(f"只有1个视频,使用批量上传按钮上传")
|
||||
batch_upload_btn.click.to_upload(video_file_paths)
|
||||
logger.info(f"✓ 已触发上传")
|
||||
else:
|
||||
logger.warning("✗ 未找到'支持批量上传'按钮,尝试使用'添加视频'按钮")
|
||||
# 使用单个上传(兼容旧版本或只有一个视频的情况)
|
||||
upload_btn = creator_tab.ele("x://*[text()='添加视频']", timeout=3)
|
||||
if upload_btn:
|
||||
logger.info("✓ 找到'添加视频'按钮")
|
||||
logger.info(f"使用添加视频按钮,准备上传 {len(video_file_paths)} 个视频")
|
||||
logger.info(f"上传文件列表: {[str(p) for p in video_file_paths]}")
|
||||
upload_btn.click.to_upload(video_file_paths)
|
||||
logger.info(f"✓ 已触发上传,上传 {len(video_file_paths)} 个视频")
|
||||
else:
|
||||
logger.error("✗ 未找到任何上传按钮!")
|
||||
|
||||
logger.info("等待上传完成...")
|
||||
time.sleep(5)
|
||||
|
||||
# 输入视频描述(只输入第一个视频的描述,因为批量上传后可能需要单独处理每个视频)
|
||||
if video_file_paths:
|
||||
first_video_name = video_file_paths[0].name
|
||||
file_names = first_video_name.split("-")
|
||||
if len(file_names) > 0:
|
||||
desc_text = file_names[-1].split(".")[0] + self.ht
|
||||
logger.info(f"准备输入视频描述: {desc_text[:50]}...")
|
||||
desc_input = creator_tab.ele(f'x://*[@id="magicdomid1"]', timeout=3)
|
||||
if desc_input:
|
||||
desc_input.input(vals=desc_text, clear=True)
|
||||
logger.info(f"✓ 已输入视频描述")
|
||||
else:
|
||||
logger.warning("✗ 未找到描述输入框")
|
||||
else:
|
||||
logger.warning("未找到任何视频文件,跳过视频上传")
|
||||
|
||||
# 第三步:如果有图片文件夹,逐个上传图片
|
||||
if image_folder_paths:
|
||||
logger.info(f"找到 {len(image_folder_paths)} 个图片文件夹,开始逐个上传...")
|
||||
for image_folder_path in image_folder_paths:
|
||||
image_files = []
|
||||
# 收集图片文件夹中的所有图片文件
|
||||
if image_folder_path.is_dir():
|
||||
for img_file in os.listdir(image_folder_path):
|
||||
img_path = Path(os.path.join(image_folder_path, img_file))
|
||||
if img_path.is_file() and any(img_path.suffix.lower() == ext for ext in image_extensions):
|
||||
image_files.append(str(img_path))
|
||||
|
||||
if image_files:
|
||||
creator_tab.ele('x://*[text()="添加图片"]').click.to_upload(image_files)
|
||||
time.sleep(3)
|
||||
|
||||
# 提取文件夹名称用于标题和描述
|
||||
folder_name = image_folder_path.name
|
||||
file_names = folder_name.split("-")
|
||||
if len(file_names) > 1:
|
||||
creator_tab.ele('x://*[@placeholder="添加标题"]').input(vals=file_names[1], clear=True)
|
||||
|
||||
xpath_path = creator_tab.ele('x://*[text()="添加视频描述"]').xpath
|
||||
# 方法2:使用正则表达式替换最后一个div[1]
|
||||
new_path = re.sub(r'div\[1\]$', 'div[2]', xpath_path)
|
||||
new_path += "/div/div[3]/div/div/div"
|
||||
|
||||
xpath_path = creator_tab.ele('x://*[text()="添加视频描述"]').xpath
|
||||
# 方法2:使用正则表达式替换最后一个div[1]
|
||||
new_path = re.sub(r'div\[1\]$', 'div[2]', xpath_path)
|
||||
new_path += "/div/div[3]/div/div/div"
|
||||
if len(file_names) > 2:
|
||||
creator_tab.ele(f'x:{new_path}').input(vals=file_names[2] + " " + self.ht, clear=True)
|
||||
break
|
||||
logger.info(f"已上传图片文件夹: {folder_name}")
|
||||
|
||||
# if ".mp4" in file_path:
|
||||
# # 上传视频
|
||||
@@ -640,22 +782,55 @@ class Pdd:
|
||||
datas[self.user_id] = creator_tab.url
|
||||
|
||||
# 批量上传视频
|
||||
logger.info("=" * 50)
|
||||
logger.info("开始准备批量上传视频...")
|
||||
videos = []
|
||||
for i in folder_path:
|
||||
videos.append(i["path"])
|
||||
for idx, video_info in enumerate(folder_path, 1):
|
||||
video_path = video_info["path"]
|
||||
videos.append(video_path)
|
||||
logger.info(f" {idx}. {video_path.name} ({video_path})")
|
||||
|
||||
logger.info(f"开始批量上传 {len(videos)} 个视频")
|
||||
creator_tab.ele("x://*[text()='支持批量上传']").click.to_upload(videos)
|
||||
logger.info(f"=" * 50)
|
||||
logger.info(f"准备批量上传 {len(videos)} 个视频")
|
||||
logger.info(f"视频文件列表: {[str(v) for v in videos]}")
|
||||
|
||||
# 优先使用"支持批量上传"按钮,如果没有则使用"添加视频"按钮
|
||||
logger.info("查找上传按钮...")
|
||||
batch_upload_btn = creator_tab.ele("x://*[text()='支持批量上传']", timeout=3)
|
||||
if batch_upload_btn:
|
||||
logger.info("✓ 找到'支持批量上传'按钮")
|
||||
logger.info(f"使用批量上传按钮,准备上传 {len(videos)} 个视频")
|
||||
batch_upload_btn.click.to_upload(videos)
|
||||
logger.info(f"✓ 已触发批量上传,上传 {len(videos)} 个视频")
|
||||
else:
|
||||
logger.warning("✗ 未找到'支持批量上传'按钮,尝试使用'添加视频'按钮")
|
||||
# 备用方案:使用"添加视频"按钮(可能也支持批量上传)
|
||||
add_video_btn = creator_tab.ele("x://*[text()='添加视频']", timeout=3)
|
||||
if add_video_btn:
|
||||
logger.info("✓ 找到'添加视频'按钮")
|
||||
logger.info(f"使用添加视频按钮,准备上传 {len(videos)} 个视频")
|
||||
add_video_btn.click.to_upload(videos)
|
||||
logger.info(f"✓ 已触发上传,上传 {len(videos)} 个视频")
|
||||
else:
|
||||
logger.error("✗ 未找到任何视频上传按钮!")
|
||||
return
|
||||
|
||||
# 等待一段时间让视频开始上传和页面渲染
|
||||
logger.info("=" * 50)
|
||||
logger.info("等待视频开始上传和页面渲染...")
|
||||
logger.info(f"已上传 {len(videos)} 个视频,等待 {5} 秒...")
|
||||
time.sleep(5)
|
||||
|
||||
# 不等待所有视频上传完成,而是检测每个视频的状态
|
||||
# 只处理已上传完成的视频,跳过还在上传中的视频
|
||||
logger.info("检测视频上传状态,只处理已上传完成的视频...")
|
||||
logger.info("=" * 50)
|
||||
logger.info("开始检测视频上传状态,只处理已上传完成的视频...")
|
||||
logger.info(f"需要处理的视频总数: {len(folder_path)}")
|
||||
|
||||
# 针对每个视频单独处理
|
||||
logger.info("=" * 50)
|
||||
logger.info(f"开始处理 {len(folder_path)} 个视频的详细信息...")
|
||||
|
||||
for idx, video_info in enumerate(folder_path):
|
||||
try:
|
||||
video_path = video_info["path"]
|
||||
@@ -664,73 +839,102 @@ class Pdd:
|
||||
video_time_start = video_info.get("time_start", self.time_start)
|
||||
video_url = video_info.get("url", self.url)
|
||||
|
||||
logger.info(f"处理第 {idx + 1}/{len(folder_path)} 个视频: {video_name}")
|
||||
logger.info("=" * 50)
|
||||
logger.info(f"处理第 {idx + 1}/{len(folder_path)} 个视频")
|
||||
logger.info(f" 视频名称: {video_name}")
|
||||
logger.info(f" 视频路径: {video_path}")
|
||||
logger.info(f" 话题: {video_ht}")
|
||||
logger.info(f" 定时时间: {video_time_start}")
|
||||
logger.info(f" 绑定URL: {video_url[:50] if video_url else 'None'}...")
|
||||
|
||||
# 定位视频容器:优先按文件名匹配,其次按索引
|
||||
logger.info(f" 正在定位视频容器...")
|
||||
video_container = None
|
||||
video_name_without_ext = video_name.rsplit(".", 1)[0]
|
||||
logger.info(f" 完整文件名: {video_name}")
|
||||
logger.info(f" 不含扩展名: {video_name_without_ext}")
|
||||
|
||||
container_xpath = (
|
||||
'x://p[contains(text(), "文件名:") and contains(text(), "{name}")]'
|
||||
'/ancestor::div[contains(@class, "y0VjbyIp")][1]'
|
||||
)
|
||||
|
||||
logger.info(f" 方法1: 按完整文件名匹配...")
|
||||
video_container = creator_tab.ele(
|
||||
container_xpath.format(name=video_name), timeout=5
|
||||
)
|
||||
if not video_container:
|
||||
if video_container:
|
||||
logger.info(f" ✓ 通过完整文件名找到视频容器")
|
||||
else:
|
||||
logger.info(f" ✗ 未找到,尝试不含扩展名...")
|
||||
video_container = creator_tab.ele(
|
||||
container_xpath.format(name=video_name_without_ext), timeout=3
|
||||
)
|
||||
if video_container:
|
||||
logger.info(f" ✓ 通过不含扩展名找到视频容器")
|
||||
|
||||
if not video_container:
|
||||
logger.info(f" ✗ 按文件名未找到,尝试按索引匹配...")
|
||||
containers = creator_tab.eles(
|
||||
'x://p[contains(text(), "文件名:")]'
|
||||
'/ancestor::div[contains(@class, "y0VjbyIp")][1]'
|
||||
)
|
||||
logger.info(f" 页面上共有 {len(containers)} 个视频容器")
|
||||
if idx < len(containers):
|
||||
video_container = containers[idx]
|
||||
logger.warning(
|
||||
f"通过索引方式定位到视频容器: {idx + 1}/{len(containers)}"
|
||||
f" ✓ 通过索引方式定位到视频容器: {idx + 1}/{len(containers)}"
|
||||
)
|
||||
else:
|
||||
logger.error(f" ✗ 索引超出范围: {idx} >= {len(containers)}")
|
||||
|
||||
if not video_container:
|
||||
logger.warning(f"未找到视频 {video_name} 的容器,跳过")
|
||||
logger.error(f" ✗ 未找到视频 {video_name} 的容器,跳过该视频")
|
||||
continue
|
||||
else:
|
||||
logger.info(f" ✓ 成功定位到视频容器")
|
||||
|
||||
# 检测上传状态(在当前视频容器内)
|
||||
logger.info(f" 检测视频上传状态...")
|
||||
# 优先判断是否仍在上传,其次判断发布按钮是否可用
|
||||
uploading_text = video_container.ele(
|
||||
'x://*[contains(., "视频上传中")]', timeout=0.5
|
||||
)
|
||||
if uploading_text:
|
||||
logger.warning(f"视频 {video_name} 还在上传中,跳过处理")
|
||||
logger.warning(f" ✗ 视频 {video_name} 还在上传中,跳过处理")
|
||||
continue
|
||||
|
||||
success_text = video_container.ele(
|
||||
'x://*[contains(., "视频上传成功")]', timeout=0.5
|
||||
)
|
||||
if success_text:
|
||||
logger.info(f"检测到视频 {video_name} 上传成功标识")
|
||||
logger.info(f" ✓ 检测到视频 {video_name} 上传成功标识")
|
||||
else:
|
||||
logger.info(f" 未找到'上传成功'标识,检查发布按钮状态...")
|
||||
# 备用判断:发布按钮未禁用即可认为已完成
|
||||
disabled_publish = video_container.ele(
|
||||
'x://button[@data-testid="beast-core-button" and (@disabled or contains(@class, "BTN_disabled"))]//span[text()="发布"]',
|
||||
timeout=0.5
|
||||
)
|
||||
if disabled_publish:
|
||||
logger.warning(f"视频 {video_name} 发布按钮仍禁用,跳过")
|
||||
logger.warning(f" ✗ 视频 {video_name} 发布按钮仍禁用,跳过")
|
||||
continue
|
||||
logger.info(f"未检测到成功标识,但发布按钮可用,继续处理 {video_name}")
|
||||
logger.info(f" ✓ 未检测到成功标识,但发布按钮可用,继续处理 {video_name}")
|
||||
|
||||
# 1. 输入视频描述
|
||||
logger.info(f" 步骤1: 输入视频描述...")
|
||||
try:
|
||||
desc_text = video_name.split(".")[0].split("-")[-1] + video_ht
|
||||
logger.info(f" 描述文本: {desc_text[:50]}...")
|
||||
desc_inputs = video_container.eles('x://*[starts-with(@id, "magicdomid")]')
|
||||
if desc_inputs:
|
||||
logger.info(f" 找到 {len(desc_inputs)} 个描述输入框,使用第一个")
|
||||
desc_inputs[0].input(vals=desc_text, clear=True)
|
||||
logger.info(f"已输入视频描述: {desc_text[:50]}...")
|
||||
logger.info(f" ✓ 已输入视频描述")
|
||||
else:
|
||||
logger.warning("在视频容器中未找到描述输入框")
|
||||
logger.warning(f" ✗ 在视频容器中未找到描述输入框")
|
||||
except Exception as e:
|
||||
logger.warning(f"输入视频描述失败: {e}")
|
||||
logger.warning(f" ✗ 输入视频描述失败: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
@@ -752,51 +956,63 @@ class Pdd:
|
||||
# 设置定时时间
|
||||
self._set_schedule_time(creator_tab, video_time_start, video_container, idx)
|
||||
except Exception as e:
|
||||
logger.warning(f"设置定时任务失败: {e}")
|
||||
logger.warning(f" ✗ 设置定时任务失败: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
else:
|
||||
logger.info(f" 步骤2: 跳过定时任务(未设置定时时间)")
|
||||
|
||||
# 3. 绑定任务(如果该视频有URL)
|
||||
if video_url:
|
||||
logger.info(f" 步骤3: 绑定任务...")
|
||||
logger.info(f" 绑定URL: {video_url[:50]}...")
|
||||
try:
|
||||
bind_btn = video_container.ele('x://*[text()="点击绑定任务"]', timeout=3)
|
||||
if bind_btn:
|
||||
logger.info(f" ✓ 找到绑定任务按钮")
|
||||
bind_btn.click()
|
||||
time.sleep(1)
|
||||
# 输入URL(这个输入框可能在弹窗中,使用全局查找)
|
||||
url_input = creator_tab.ele('x://*[@placeholder="请输入个人主页链接"]', timeout=3)
|
||||
if url_input:
|
||||
logger.info(f" ✓ 找到URL输入框")
|
||||
url_input.input(video_url, clear=True)
|
||||
time.sleep(1)
|
||||
confirm_btn = creator_tab.ele('x://*[text()="确认"]', timeout=3)
|
||||
if confirm_btn:
|
||||
confirm_btn.click()
|
||||
logger.info(f"已绑定任务: {video_url[:50]}...")
|
||||
logger.info(f" ✓ 已绑定任务")
|
||||
time.sleep(1)
|
||||
else:
|
||||
logger.warning(f" ✗ 未找到确认按钮")
|
||||
else:
|
||||
logger.warning("未找到URL输入框")
|
||||
logger.warning(f" ✗ 未找到URL输入框")
|
||||
else:
|
||||
logger.warning("未找到绑定任务按钮")
|
||||
logger.warning(f" ✗ 未找到绑定任务按钮")
|
||||
except Exception as e:
|
||||
logger.warning(f"绑定任务失败: {e}")
|
||||
logger.warning(f" ✗ 绑定任务失败: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
else:
|
||||
logger.info(f" 步骤3: 跳过绑定任务(未设置URL)")
|
||||
|
||||
# 4. 点击该视频的发布按钮(注意:这里应该是单个视频的"发布"按钮,不是"立即发布")
|
||||
logger.info(f" 步骤4: 点击发布按钮...")
|
||||
try:
|
||||
publish_btn = video_container.ele(
|
||||
'x://button[@data-testid="beast-core-button"]//span[text()="发布"]', timeout=3
|
||||
)
|
||||
if publish_btn:
|
||||
publish_btn.click()
|
||||
logger.info("已点击发布按钮")
|
||||
logger.info(f" ✓ 已点击发布按钮")
|
||||
else:
|
||||
logger.warning("在视频容器中未找到发布按钮")
|
||||
logger.warning(f" ✗ 在视频容器中未找到发布按钮")
|
||||
except Exception as e:
|
||||
logger.warning(f"点击发布按钮失败: {e}")
|
||||
logger.warning(f" ✗ 点击发布按钮失败: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
logger.info(f" ✓ 视频 {video_name} 处理完成")
|
||||
time.sleep(2) # 每个视频处理间隔
|
||||
|
||||
except Exception as e:
|
||||
|
||||
@@ -5,4 +5,3 @@ loguru>=0.6.0
|
||||
beautifulsoup4>=4.9.0
|
||||
curl-cffi>=0.5.0
|
||||
DrissionPage>=4.0.0
|
||||
qfluentwidgets
|
||||
|
||||
@@ -8,5 +8,5 @@
|
||||
"top_topics_and_observing_domains": [ ]
|
||||
} ],
|
||||
"hex_encoded_hmac_key": "434BF7DBD7DA573B45E0A11AD9045A61B6221D14AE2F9A341E2FEF659AF071F6",
|
||||
"next_scheduled_calculation_time": "13413450070590271"
|
||||
"next_scheduled_calculation_time": "13413450070590344"
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 243 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 572 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 143 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 354 KiB |
BIN
user/user_data/Default/Cache/Cache_Data/f_00000d
Normal file
BIN
user/user_data/Default/Cache/Cache_Data/f_00000e
Normal file
BIN
user/user_data/Default/Cache/Cache_Data/f_00000f
Normal file
BIN
user/user_data/Default/Cache/Cache_Data/f_000010
Normal file
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 238 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 20 KiB |
BIN
user/user_data/Default/Cache/Cache_Data/f_000014
Normal file
|
After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 426 KiB |
|
Before Width: | Height: | Size: 352 KiB After Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 50 KiB |
BIN
user/user_data/Default/Cache/Cache_Data/f_000022
Normal file
|
Before Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 153 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 414 KiB |
|
Before Width: | Height: | Size: 437 KiB |
|
Before Width: | Height: | Size: 153 KiB |
|
Before Width: | Height: | Size: 153 KiB |
|
Before Width: | Height: | Size: 153 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 153 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 153 KiB |
|
Before Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 396 KiB |
|
Before Width: | Height: | Size: 316 KiB |
|
Before Width: | Height: | Size: 133 KiB |
|
Before Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 177 KiB |
|
Before Width: | Height: | Size: 386 KiB |
|
Before Width: | Height: | Size: 305 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 50 KiB |