1. 抖音我这边遇到必须上传封面的情况,自动设置第一个推荐封面(大概率首帧)
Browse files- conf.example.py +1 -1
- uploader/douyin_uploader/main.py +39 -1
conf.example.py
CHANGED
|
@@ -3,4 +3,4 @@ from pathlib import Path
|
|
| 3 |
BASE_DIR = Path(__file__).parent.resolve()
|
| 4 |
XHS_SERVER = "http://127.0.0.1:11901"
|
| 5 |
LOCAL_CHROME_PATH = "" # change me necessary! for example C:/Program Files/Google/Chrome/Application/chrome.exe
|
| 6 |
-
LOCAL_CHROME_HEADLESS =
|
|
|
|
| 3 |
BASE_DIR = Path(__file__).parent.resolve()
|
| 4 |
XHS_SERVER = "http://127.0.0.1:11901"
|
| 5 |
LOCAL_CHROME_PATH = "" # change me necessary! for example C:/Program Files/Google/Chrome/Application/chrome.exe
|
| 6 |
+
LOCAL_CHROME_HEADLESS = False
|
uploader/douyin_uploader/main.py
CHANGED
|
@@ -213,6 +213,8 @@ class DouYinVideo(object):
|
|
| 213 |
douyin_logger.success(" [-]视频发布成功")
|
| 214 |
break
|
| 215 |
except:
|
|
|
|
|
|
|
| 216 |
douyin_logger.info(" [-] 视频正在发布中...")
|
| 217 |
await page.screenshot(full_page=True)
|
| 218 |
await asyncio.sleep(0.5)
|
|
@@ -223,7 +225,43 @@ class DouYinVideo(object):
|
|
| 223 |
# 关闭浏览器上下文和浏览器实例
|
| 224 |
await context.close()
|
| 225 |
await browser.close()
|
| 226 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 227 |
async def set_thumbnail(self, page: Page, thumbnail_path: str):
|
| 228 |
if thumbnail_path:
|
| 229 |
douyin_logger.info(' [-] 正在设置视频封面...')
|
|
|
|
| 213 |
douyin_logger.success(" [-]视频发布成功")
|
| 214 |
break
|
| 215 |
except:
|
| 216 |
+
# 尝试处理封面问题
|
| 217 |
+
await self.handle_auto_video_cover(page)
|
| 218 |
douyin_logger.info(" [-] 视频正在发布中...")
|
| 219 |
await page.screenshot(full_page=True)
|
| 220 |
await asyncio.sleep(0.5)
|
|
|
|
| 225 |
# 关闭浏览器上下文和浏览器实例
|
| 226 |
await context.close()
|
| 227 |
await browser.close()
|
| 228 |
+
|
| 229 |
+
async def handle_auto_video_cover(self, page):
|
| 230 |
+
"""
|
| 231 |
+
处理必须设置封面的情况,点击推荐封面的第一个
|
| 232 |
+
"""
|
| 233 |
+
# 1. 判断是否出现 "请设置封面后再发布" 的提示
|
| 234 |
+
# 必须确保提示是可见的 (is_visible),因为 DOM 中可能存在隐藏的历史提示
|
| 235 |
+
if await page.get_by_text("请设置封面后再发布").first.is_visible():
|
| 236 |
+
print(" [-] 检测到需要设置封面提示...")
|
| 237 |
+
|
| 238 |
+
# 2. 定位“智能推荐封面”区域下的第一个封面
|
| 239 |
+
# 使用 class^= 前缀匹配,避免 hash 变化导致失效
|
| 240 |
+
recommend_cover = page.locator('[class^="recommendCover-"]').first
|
| 241 |
+
|
| 242 |
+
if await recommend_cover.count():
|
| 243 |
+
print(" [-] 正在选择第一个推荐封面...")
|
| 244 |
+
try:
|
| 245 |
+
await recommend_cover.click()
|
| 246 |
+
await asyncio.sleep(1) # 等待选中生效
|
| 247 |
+
|
| 248 |
+
# 3. 处理可能的确认弹窗 "是否确认应用此封面?"
|
| 249 |
+
# 并不一定每次都会出现,健壮性判断:如果出现弹窗,则点击确定
|
| 250 |
+
confirm_text = "是否确认应用此封面?"
|
| 251 |
+
if await page.get_by_text(confirm_text).first.is_visible():
|
| 252 |
+
print(f" [-] 检测到确认弹窗: {confirm_text}")
|
| 253 |
+
# 直接点击“确定”按钮,不依赖脆弱的 CSS 类名
|
| 254 |
+
await page.get_by_role("button", name="确定").click()
|
| 255 |
+
print(" [-] 已点击确认应用封面")
|
| 256 |
+
await asyncio.sleep(1)
|
| 257 |
+
|
| 258 |
+
print(" [-] 已完成封面选择流程")
|
| 259 |
+
return True
|
| 260 |
+
except Exception as e:
|
| 261 |
+
print(f" [-] 选择封面失败: {e}")
|
| 262 |
+
|
| 263 |
+
return False
|
| 264 |
+
|
| 265 |
async def set_thumbnail(self, page: Page, thumbnail_path: str):
|
| 266 |
if thumbnail_path:
|
| 267 |
douyin_logger.info(' [-] 正在设置视频封面...')
|