pookz@stme commited on
Commit
8b6dbdc
·
1 Parent(s): 0ef83f2

1. use loguru for clean console message

Browse files
bilibili_uploader/main.py CHANGED
@@ -3,6 +3,8 @@ import pathlib
3
  import random
4
  from biliup.plugins.bili_webup import BiliBili, Data
5
 
 
 
6
 
7
  def extract_keys_from_json(data):
8
  """Extract specified keys from the provided JSON data."""
@@ -70,8 +72,8 @@ class BilibiliUploader(object):
70
  self.data.append(video_part)
71
  ret = bili.submit() # 提交视频
72
  if ret.get('code') == 0:
73
- print(f'[+] {self.file.name}上传 成功')
74
  return True
75
  else:
76
- print(f'[-] {self.file.name}上传 失败, error messge: {ret.get("message")}')
77
  return False
 
3
  import random
4
  from biliup.plugins.bili_webup import BiliBili, Data
5
 
6
+ from utils.log import bilibili_logger
7
+
8
 
9
  def extract_keys_from_json(data):
10
  """Extract specified keys from the provided JSON data."""
 
72
  self.data.append(video_part)
73
  ret = bili.submit() # 提交视频
74
  if ret.get('code') == 0:
75
+ bilibili_logger.success(f'[+] {self.file.name}上传 成功')
76
  return True
77
  else:
78
+ bilibili_logger.error(f'[-] {self.file.name}上传 失败, error messge: {ret.get("message")}')
79
  return False
douyin_uploader/main.py CHANGED
@@ -7,6 +7,7 @@ import asyncio
7
 
8
  from conf import LOCAL_CHROME_PATH
9
  from utils.base_social_media import set_init_script
 
10
 
11
 
12
  async def cookie_auth(account_file):
@@ -20,10 +21,10 @@ async def cookie_auth(account_file):
20
  await page.goto("https://creator.douyin.com/creator-micro/content/upload")
21
  try:
22
  await page.wait_for_selector("div.boards-more h3:text('抖音排行榜')", timeout=5000) # 等待5秒
23
- print("[+] 等待5秒 cookie 失效")
24
  return False
25
  except:
26
- print("[+] cookie 有效")
27
  return True
28
 
29
 
@@ -32,7 +33,7 @@ async def douyin_setup(account_file, handle=False):
32
  if not handle:
33
  # Todo alert message
34
  return False
35
- print('[+] cookie文件不存在或已失效,即将自动打开浏览器,请扫码登录,登陆后会自动生成cookie文件')
36
  await douyin_cookie_gen(account_file)
37
  return True
38
 
@@ -82,7 +83,7 @@ class DouYinVideo(object):
82
  await asyncio.sleep(1)
83
 
84
  async def handle_upload_error(self, page):
85
- print("视频出错了,重新上传中")
86
  await page.locator('div.progress-div [class^="upload-btn-input"]').set_input_files(self.file_path)
87
 
88
  async def upload(self, playwright: Playwright) -> None:
@@ -99,9 +100,9 @@ class DouYinVideo(object):
99
  page = await context.new_page()
100
  # 访问指定的 URL
101
  await page.goto("https://creator.douyin.com/creator-micro/content/upload")
102
- print('[+]正在上传-------{}.mp4'.format(self.title))
103
  # 等待页面跳转到指定的 URL,没进入,则自动等待到超时
104
- print('[-] 正在打开主页...')
105
  await page.wait_for_url("https://creator.douyin.com/creator-micro/content/upload")
106
  # 点击 "上传视频" 按钮
107
  await page.locator(".upload-btn--9eZLd").set_input_files(self.file_path)
@@ -114,32 +115,30 @@ class DouYinVideo(object):
114
  "https://creator.douyin.com/creator-micro/content/publish?enter_from=publish_page")
115
  break
116
  except:
117
- print(" [-] 正在等待进入视频发布页面...")
118
  await asyncio.sleep(0.1)
119
 
120
  # 填充标题和话题
121
  # 检查是否存在包含输入框的元素
122
  # 这里为了避免页面变化,故使用相对位置定位:作品标题父级右侧第一个元素的input子元素
123
  await asyncio.sleep(1)
124
- print(" [-] 正在填充标题和话题...")
125
  title_container = page.get_by_text('作品标题').locator("..").locator("xpath=following-sibling::div[1]").locator("input")
126
  if await title_container.count():
127
  await title_container.fill(self.title[:30])
128
  else:
129
  titlecontainer = page.locator(".notranslate")
130
  await titlecontainer.click()
131
- print("clear existing title")
132
  await page.keyboard.press("Backspace")
133
  await page.keyboard.press("Control+KeyA")
134
  await page.keyboard.press("Delete")
135
- print("filling new title")
136
  await page.keyboard.type(self.title)
137
  await page.keyboard.press("Enter")
138
  css_selector = ".zone-container"
139
  for index, tag in enumerate(self.tags, start=1):
140
- print("正在添加第%s个话题" % index)
141
  await page.type(css_selector, "#" + tag)
142
  await page.press(css_selector, "Space")
 
143
 
144
  while True:
145
  # 判断重新上传按钮是否存在,如果不存在,代表视频正在上传,则等待
@@ -147,23 +146,22 @@ class DouYinVideo(object):
147
  # 新版:定位重新上传
148
  number = await page.locator('div label+div:has-text("重新上传")').count()
149
  if number > 0:
150
- print(" [-]视频上传完毕")
151
  break
152
  else:
153
- print(" [-] 正在上传视频中...")
154
  await asyncio.sleep(2)
155
 
156
  if await page.locator('div.progress-div > div:has-text("上传失败")').count():
157
- print(" [-] 发现上传出错了...")
158
  await self.handle_upload_error(page)
159
  except:
160
- print(" [-] 正在上传视频中...")
161
  await asyncio.sleep(2)
162
 
163
  # 更换可见元素
164
  await page.locator('div.semi-select span:has-text("输入地理位置")').click()
165
  await asyncio.sleep(1)
166
- print("clear existing location")
167
  await page.keyboard.press("Backspace")
168
  await page.keyboard.press("Control+KeyA")
169
  await page.keyboard.press("Delete")
@@ -192,15 +190,15 @@ class DouYinVideo(object):
192
  await publish_button.click()
193
  await page.wait_for_url("https://creator.douyin.com/creator-micro/content/manage",
194
  timeout=1500) # 如果自动跳转到作品页面,则代表发布成功
195
- print(" [-]视频发布成功")
196
  break
197
  except:
198
- print(" [-] 视频正在发布中...")
199
  await page.screenshot(full_page=True)
200
  await asyncio.sleep(0.5)
201
 
202
  await context.storage_state(path=self.account_file) # 保存cookie
203
- print(' [-]cookie更新完毕!')
204
  await asyncio.sleep(2) # 这里延迟是为了方便眼睛直观的观看
205
  # 关闭浏览器上下文和浏览器实例
206
  await context.close()
 
7
 
8
  from conf import LOCAL_CHROME_PATH
9
  from utils.base_social_media import set_init_script
10
+ from utils.log import douyin_logger
11
 
12
 
13
  async def cookie_auth(account_file):
 
21
  await page.goto("https://creator.douyin.com/creator-micro/content/upload")
22
  try:
23
  await page.wait_for_selector("div.boards-more h3:text('抖音排行榜')", timeout=5000) # 等待5秒
24
+ douyin_logger.error(f'等待5秒 cookie 失效')
25
  return False
26
  except:
27
+ douyin_logger.success(f'cookie 有效')
28
  return True
29
 
30
 
 
33
  if not handle:
34
  # Todo alert message
35
  return False
36
+ douyin_logger.info('[+] cookie文件不存在或已失效,即将自动打开浏览器,请扫码登录,登陆后会自动生成cookie文件')
37
  await douyin_cookie_gen(account_file)
38
  return True
39
 
 
83
  await asyncio.sleep(1)
84
 
85
  async def handle_upload_error(self, page):
86
+ douyin_logger.info('视频出错了,重新上传中')
87
  await page.locator('div.progress-div [class^="upload-btn-input"]').set_input_files(self.file_path)
88
 
89
  async def upload(self, playwright: Playwright) -> None:
 
100
  page = await context.new_page()
101
  # 访问指定的 URL
102
  await page.goto("https://creator.douyin.com/creator-micro/content/upload")
103
+ douyin_logger.info(f'[+]正在上传-------{self.title}.mp4')
104
  # 等待页面跳转到指定的 URL,没进入,则自动等待到超时
105
+ douyin_logger.info(f'[-] 正在打开主页...')
106
  await page.wait_for_url("https://creator.douyin.com/creator-micro/content/upload")
107
  # 点击 "上传视频" 按钮
108
  await page.locator(".upload-btn--9eZLd").set_input_files(self.file_path)
 
115
  "https://creator.douyin.com/creator-micro/content/publish?enter_from=publish_page")
116
  break
117
  except:
118
+ douyin_logger.info(f' [-] 正在等待进入视频发布页面...')
119
  await asyncio.sleep(0.1)
120
 
121
  # 填充标题和话题
122
  # 检查是否存在包含输入框的元素
123
  # 这里为了避免页面变化,故使用相对位置定位:作品标题父级右侧第一个元素的input子元素
124
  await asyncio.sleep(1)
125
+ douyin_logger.info(f' [-] 正在填充标题和话题...')
126
  title_container = page.get_by_text('作品标题').locator("..").locator("xpath=following-sibling::div[1]").locator("input")
127
  if await title_container.count():
128
  await title_container.fill(self.title[:30])
129
  else:
130
  titlecontainer = page.locator(".notranslate")
131
  await titlecontainer.click()
 
132
  await page.keyboard.press("Backspace")
133
  await page.keyboard.press("Control+KeyA")
134
  await page.keyboard.press("Delete")
 
135
  await page.keyboard.type(self.title)
136
  await page.keyboard.press("Enter")
137
  css_selector = ".zone-container"
138
  for index, tag in enumerate(self.tags, start=1):
 
139
  await page.type(css_selector, "#" + tag)
140
  await page.press(css_selector, "Space")
141
+ douyin_logger.info(f'总共添加{len(self.tags)}个话题')
142
 
143
  while True:
144
  # 判断重新上传按钮是否存在,如果不存在,代表视频正在上传,则等待
 
146
  # 新版:定位重新上传
147
  number = await page.locator('div label+div:has-text("重新上传")').count()
148
  if number > 0:
149
+ douyin_logger.success(" [-]视频上传完毕")
150
  break
151
  else:
152
+ douyin_logger.info(" [-] 正在上传视频中...")
153
  await asyncio.sleep(2)
154
 
155
  if await page.locator('div.progress-div > div:has-text("上传失败")').count():
156
+ douyin_logger.error(" [-] 发现上传出错了... 准备重试")
157
  await self.handle_upload_error(page)
158
  except:
159
+ douyin_logger.info(" [-] 正在上传视频中...")
160
  await asyncio.sleep(2)
161
 
162
  # 更换可见元素
163
  await page.locator('div.semi-select span:has-text("输入地理位置")').click()
164
  await asyncio.sleep(1)
 
165
  await page.keyboard.press("Backspace")
166
  await page.keyboard.press("Control+KeyA")
167
  await page.keyboard.press("Delete")
 
190
  await publish_button.click()
191
  await page.wait_for_url("https://creator.douyin.com/creator-micro/content/manage",
192
  timeout=1500) # 如果自动跳转到作品页面,则代表发布成功
193
+ douyin_logger.success(" [-]视频发布成功")
194
  break
195
  except:
196
+ douyin_logger.info(" [-] 视频正在发布中...")
197
  await page.screenshot(full_page=True)
198
  await asyncio.sleep(0.5)
199
 
200
  await context.storage_state(path=self.account_file) # 保存cookie
201
+ douyin_logger.success(' [-]cookie更新完毕!')
202
  await asyncio.sleep(2) # 这里延迟是为了方便眼睛直观的观看
203
  # 关闭浏览器上下文和浏览器实例
204
  await context.close()
requirements.txt CHANGED
@@ -5,4 +5,5 @@ schedule
5
  cf_clearance
6
  biliup
7
  xhs
8
- qrcode
 
 
5
  cf_clearance
6
  biliup
7
  xhs
8
+ qrcode
9
+ loguru
tencent_uploader/main.py CHANGED
@@ -8,6 +8,7 @@ import asyncio
8
  from conf import LOCAL_CHROME_PATH
9
  from utils.base_social_media import set_init_script
10
  from utils.files_times import get_absolute_path
 
11
 
12
 
13
  def format_str_for_short_title(origin_title: str) -> str:
@@ -41,10 +42,10 @@ async def cookie_auth(account_file):
41
  await page.goto("https://channels.weixin.qq.com/platform/post/create")
42
  try:
43
  await page.wait_for_selector('div.title-name:has-text("视频号小店")', timeout=5000) # 等待5秒
44
- print("[+] 等待5秒 cookie 失效")
45
  return False
46
  except:
47
- print("[+] cookie 有效")
48
  return True
49
 
50
 
@@ -75,7 +76,7 @@ async def weixin_setup(account_file, handle=False):
75
  if not handle:
76
  # Todo alert message
77
  return False
78
- print('[+] cookie文件不存在或已失效,即将自动打开浏览器,请扫码登录,登陆后会自动生成cookie文件')
79
  await get_tencent_cookie(account_file)
80
  return True
81
 
@@ -91,8 +92,6 @@ class TencentVideo(object):
91
  self.local_executable_path = LOCAL_CHROME_PATH
92
 
93
  async def set_schedule_time_tencent(self, page, publish_date):
94
- print("click schedule")
95
-
96
  label_element = page.locator("label").filter(has_text="定时").nth(1)
97
  await label_element.click()
98
 
@@ -128,7 +127,7 @@ class TencentVideo(object):
128
  await page.locator("div.input-editor").click()
129
 
130
  async def handle_upload_error(self, page):
131
- print("视频出错了,重新上传中")
132
  await page.locator('div.media-status-content div.tag-inner:has-text("删除")').click()
133
  await page.get_by_role('button', name="删除", exact=True).click()
134
  file_input = page.locator('input[type="file"]')
@@ -145,7 +144,7 @@ class TencentVideo(object):
145
  page = await context.new_page()
146
  # 访问指定的 URL
147
  await page.goto("https://channels.weixin.qq.com/platform/post/create")
148
- print('[+]正在上传-------{}.mp4'.format(self.title))
149
  # 等待页面跳转到指定的 URL,没进入,则自动等待到超时
150
  await page.wait_for_url("https://channels.weixin.qq.com/platform/post/create")
151
  # await page.wait_for_selector('input[type="file"]', timeout=10000)
@@ -160,7 +159,7 @@ class TencentVideo(object):
160
  # 原创选择
161
  await self.add_original(page)
162
  # 检测上传状态
163
- await self.detact_upload_status(page)
164
  if self.publish_date != 0:
165
  await self.set_schedule_time_tencent(page, self.publish_date)
166
  # 添加短标题
@@ -169,12 +168,11 @@ class TencentVideo(object):
169
  await self.click_publish(page)
170
 
171
  await context.storage_state(path=f"{self.account_file}") # 保存cookie
172
- print(' [-]cookie更新完毕!')
173
  await asyncio.sleep(2) # 这里延迟是为了方便眼睛直观的观看
174
  # 关闭浏览器上下文和浏览器实例
175
  await context.close()
176
  await browser.close()
177
- print('[+]正在监控执行计划中.......')
178
 
179
  async def add_short_title(self, page):
180
  short_title_element = page.get_by_text("短标题", exact=True).locator("..").locator(
@@ -191,38 +189,37 @@ class TencentVideo(object):
191
  if await publish_buttion.count():
192
  await publish_buttion.click()
193
  await page.wait_for_url("https://channels.weixin.qq.com/platform/post/list", timeout=1500)
194
- print(" [-]视频发布成功")
195
  break
196
  except Exception as e:
197
  current_url = page.url
198
  if "https://channels.weixin.qq.com/platform/post/list" in current_url:
199
- print(" [-]视频发布成功")
200
  break
201
  else:
202
- print(f" [-] Exception: {e}")
203
- print(" [-] 视频正在发布中...")
204
- await page.screenshot(full_page=True)
205
  await asyncio.sleep(0.5)
206
 
207
- async def detact_upload_status(self, page):
208
  while True:
209
  # 匹配删除按钮,代表视频上传完毕,如果不存在,��表视频正在上传,则等待
210
  try:
211
  # 匹配删除按钮,代表视频上传完毕
212
  if "weui-desktop-btn_disabled" not in await page.get_by_role("button", name="发表").get_attribute(
213
  'class'):
214
- print(" [-]视频上传完毕")
215
  break
216
  else:
217
- print(" [-] 正在上传视频中...")
218
  await asyncio.sleep(2)
219
  # 出错了视频出错
220
  if await page.locator('div.status-msg.error').count() and await page.locator(
221
  'div.media-status-content div.tag-inner:has-text("删除")').count():
222
- print(" [-] 发现上传出错了...")
223
  await self.handle_upload_error(page)
224
  except:
225
- print(" [-] 正在上传视频中...")
226
  await asyncio.sleep(2)
227
 
228
  async def add_title_tags(self, page):
@@ -232,7 +229,7 @@ class TencentVideo(object):
232
  for index, tag in enumerate(self.tags, start=1):
233
  await page.keyboard.type("#" + tag)
234
  await page.keyboard.press("Space")
235
- print(f"成功添加hashtag: {len(self.tags)}")
236
 
237
  async def add_collection(self, page):
238
  collection_elements = page.get_by_text("添加到合集").locator("xpath=following-sibling::div").locator(
 
8
  from conf import LOCAL_CHROME_PATH
9
  from utils.base_social_media import set_init_script
10
  from utils.files_times import get_absolute_path
11
+ from utils.log import tencent_logger
12
 
13
 
14
  def format_str_for_short_title(origin_title: str) -> str:
 
42
  await page.goto("https://channels.weixin.qq.com/platform/post/create")
43
  try:
44
  await page.wait_for_selector('div.title-name:has-text("视频号小店")', timeout=5000) # 等待5秒
45
+ tencent_logger.error("[+] 等待5秒 cookie 失效")
46
  return False
47
  except:
48
+ tencent_logger.success("[+] cookie 有效")
49
  return True
50
 
51
 
 
76
  if not handle:
77
  # Todo alert message
78
  return False
79
+ tencent_logger.info('[+] cookie文件不存在或已失效,即将自动打开浏览器,请扫码登录,登陆后会自动生成cookie文件')
80
  await get_tencent_cookie(account_file)
81
  return True
82
 
 
92
  self.local_executable_path = LOCAL_CHROME_PATH
93
 
94
  async def set_schedule_time_tencent(self, page, publish_date):
 
 
95
  label_element = page.locator("label").filter(has_text="定时").nth(1)
96
  await label_element.click()
97
 
 
127
  await page.locator("div.input-editor").click()
128
 
129
  async def handle_upload_error(self, page):
130
+ tencent_logger.info("视频出错了,重新上传中")
131
  await page.locator('div.media-status-content div.tag-inner:has-text("删除")').click()
132
  await page.get_by_role('button', name="删除", exact=True).click()
133
  file_input = page.locator('input[type="file"]')
 
144
  page = await context.new_page()
145
  # 访问指定的 URL
146
  await page.goto("https://channels.weixin.qq.com/platform/post/create")
147
+ tencent_logger.info(f'[+]正在上传-------{self.title}.mp4')
148
  # 等待页面跳转到指定的 URL,没进入,则自动等待到超时
149
  await page.wait_for_url("https://channels.weixin.qq.com/platform/post/create")
150
  # await page.wait_for_selector('input[type="file"]', timeout=10000)
 
159
  # 原创选择
160
  await self.add_original(page)
161
  # 检测上传状态
162
+ await self.detect_upload_status(page)
163
  if self.publish_date != 0:
164
  await self.set_schedule_time_tencent(page, self.publish_date)
165
  # 添加短标题
 
168
  await self.click_publish(page)
169
 
170
  await context.storage_state(path=f"{self.account_file}") # 保存cookie
171
+ tencent_logger.success(' [-]cookie更新完毕!')
172
  await asyncio.sleep(2) # 这里延迟是为了方便眼睛直观的观看
173
  # 关闭浏览器上下文和浏览器实例
174
  await context.close()
175
  await browser.close()
 
176
 
177
  async def add_short_title(self, page):
178
  short_title_element = page.get_by_text("短标题", exact=True).locator("..").locator(
 
189
  if await publish_buttion.count():
190
  await publish_buttion.click()
191
  await page.wait_for_url("https://channels.weixin.qq.com/platform/post/list", timeout=1500)
192
+ tencent_logger.success(" [-]视频发布成功")
193
  break
194
  except Exception as e:
195
  current_url = page.url
196
  if "https://channels.weixin.qq.com/platform/post/list" in current_url:
197
+ tencent_logger.success(" [-]视频发布成功")
198
  break
199
  else:
200
+ tencent_logger.exception(f" [-] Exception: {e}")
201
+ tencent_logger.info(" [-] 视频正在发布中...")
 
202
  await asyncio.sleep(0.5)
203
 
204
+ async def detect_upload_status(self, page):
205
  while True:
206
  # 匹配删除按钮,代表视频上传完毕,如果不存在,��表视频正在上传,则等待
207
  try:
208
  # 匹配删除按钮,代表视频上传完毕
209
  if "weui-desktop-btn_disabled" not in await page.get_by_role("button", name="发表").get_attribute(
210
  'class'):
211
+ tencent_logger.info(" [-]视频上传完毕")
212
  break
213
  else:
214
+ tencent_logger.info(" [-] 正在上传视频中...")
215
  await asyncio.sleep(2)
216
  # 出错了视频出错
217
  if await page.locator('div.status-msg.error').count() and await page.locator(
218
  'div.media-status-content div.tag-inner:has-text("删除")').count():
219
+ tencent_logger.error(" [-] 发现上传出错了...准备重试")
220
  await self.handle_upload_error(page)
221
  except:
222
+ tencent_logger.info(" [-] 正在上传视频中...")
223
  await asyncio.sleep(2)
224
 
225
  async def add_title_tags(self, page):
 
229
  for index, tag in enumerate(self.tags, start=1):
230
  await page.keyboard.type("#" + tag)
231
  await page.keyboard.press("Space")
232
+ tencent_logger.info(f"成功添加hashtag: {len(self.tags)}")
233
 
234
  async def add_collection(self, page):
235
  collection_elements = page.get_by_text("添加到合集").locator("xpath=following-sibling::div").locator(
tk_uploader/main.py CHANGED
@@ -8,6 +8,7 @@ import asyncio
8
  from tk_uploader.tk_config import Tk_Locator
9
  from utils.base_social_media import set_init_script
10
  from utils.files_times import get_absolute_path
 
11
 
12
 
13
  async def cookie_auth(account_file):
@@ -27,12 +28,12 @@ async def cookie_auth(account_file):
27
  class_name = await element.get_attribute('class')
28
  # 使用正则表达式匹配特定模式的 class 名称
29
  if re.match(r'tiktok-.*-SelectFormContainer.*', class_name):
30
- print("[+] cookie expired")
31
  return False
32
- print("[+] cookie valid")
33
  return True
34
  except:
35
- print("[+] cookie valid")
36
  return True
37
 
38
 
@@ -41,7 +42,7 @@ async def tiktok_setup(account_file, handle=False):
41
  if not os.path.exists(account_file) or not await cookie_auth(account_file):
42
  if not handle:
43
  return False
44
- print('[+] cookie file is not existed or expired. Now open the browser auto. Please login with your way(gmail phone, whatever, the cookie file will generated after login')
45
  await get_tiktok_cookie(account_file)
46
  return True
47
 
@@ -76,7 +77,6 @@ class TiktokVideo(object):
76
  self.account_file = account_file
77
 
78
  async def set_schedule_time(self, page, publish_date):
79
- print("click schedule")
80
  schedule_input_element = page.frame_locator(Tk_Locator.tk_iframe).locator('div.scheduled-container input')
81
  await schedule_input_element.wait_for(state='visible') # 确保按钮可见
82
 
@@ -130,7 +130,7 @@ class TiktokVideo(object):
130
  await page.frame_locator(Tk_Locator.tk_iframe).locator("h1:has-text('Upload video')").click()
131
 
132
  async def handle_upload_error(self, page):
133
- print("video upload error retrying.")
134
  select_file_button = page.frame_locator(Tk_Locator.tk_iframe).locator('button[aria-label="Select file"]')
135
  async with page.expect_file_chooser() as fc_info:
136
  await select_file_button.click()
@@ -144,7 +144,7 @@ class TiktokVideo(object):
144
  page = await context.new_page()
145
 
146
  await page.goto("https://www.tiktok.com/creator-center/upload")
147
- print('[+]Uploading-------{}.mp4'.format(self.title))
148
 
149
  await page.wait_for_url("https://www.tiktok.com/tiktokstudio/upload", timeout=10000)
150
  await page.wait_for_selector('iframe[data-tt="Upload_index_iframe"]')
@@ -166,7 +166,7 @@ class TiktokVideo(object):
166
  await self.click_publish(page)
167
 
168
  await context.storage_state(path=f"{self.account_file}") # save cookie
169
- print(' [-] update cookie!')
170
  await asyncio.sleep(2) # close delay for look the video status
171
  # close all
172
  await context.close()
@@ -195,7 +195,7 @@ class TiktokVideo(object):
195
 
196
  # tag part
197
  for index, tag in enumerate(self.tags, start=1):
198
- print("Setting the %s tag" % index)
199
  await page.keyboard.press("End")
200
  await page.wait_for_timeout(1000) # 等待1秒
201
  await page.keyboard.insert_text("#" + tag + " ")
@@ -214,15 +214,15 @@ class TiktokVideo(object):
214
  await publish_button.click()
215
 
216
  await page.frame_locator(Tk_Locator.tk_iframe).locator(success_flag_div).wait_for(state="visible", timeout=1500)
217
- print(" [-] video published success")
218
  break
219
  except Exception as e:
220
  if await page.frame_locator(Tk_Locator.tk_iframe).locator(success_flag_div).count():
221
- print(" [-]video published success")
222
  break
223
  else:
224
- print(f" [-] Exception: {e}")
225
- print(" [-] video publishing")
226
  await page.screenshot(full_page=True)
227
  await asyncio.sleep(0.5)
228
 
@@ -230,16 +230,16 @@ class TiktokVideo(object):
230
  while True:
231
  try:
232
  if await page.frame_locator(Tk_Locator.tk_iframe).locator('div.btn-post > button').get_attribute("disabled") is None:
233
- print(" [-]video uploaded.")
234
  break
235
  else:
236
- print(" [-] video uploading...")
237
  await asyncio.sleep(2)
238
  if await page.frame_locator(Tk_Locator.tk_iframe).locator('button[aria-label="Select file"]').count():
239
- print(" [-] found some error while uploading now retry...")
240
  await self.handle_upload_error(page)
241
  except:
242
- print(" [-] video uploading...")
243
  await asyncio.sleep(2)
244
 
245
  async def main(self):
 
8
  from tk_uploader.tk_config import Tk_Locator
9
  from utils.base_social_media import set_init_script
10
  from utils.files_times import get_absolute_path
11
+ from utils.log import tiktok_logger
12
 
13
 
14
  async def cookie_auth(account_file):
 
28
  class_name = await element.get_attribute('class')
29
  # 使用正则表达式匹配特定模式的 class 名称
30
  if re.match(r'tiktok-.*-SelectFormContainer.*', class_name):
31
+ tiktok_logger.error("[+] cookie expired")
32
  return False
33
+ tiktok_logger.success("[+] cookie valid")
34
  return True
35
  except:
36
+ tiktok_logger.success("[+] cookie valid")
37
  return True
38
 
39
 
 
42
  if not os.path.exists(account_file) or not await cookie_auth(account_file):
43
  if not handle:
44
  return False
45
+ tiktok_logger.info('[+] cookie file is not existed or expired. Now open the browser auto. Please login with your way(gmail phone, whatever, the cookie file will generated after login')
46
  await get_tiktok_cookie(account_file)
47
  return True
48
 
 
77
  self.account_file = account_file
78
 
79
  async def set_schedule_time(self, page, publish_date):
 
80
  schedule_input_element = page.frame_locator(Tk_Locator.tk_iframe).locator('div.scheduled-container input')
81
  await schedule_input_element.wait_for(state='visible') # 确保按钮可见
82
 
 
130
  await page.frame_locator(Tk_Locator.tk_iframe).locator("h1:has-text('Upload video')").click()
131
 
132
  async def handle_upload_error(self, page):
133
+ tiktok_logger.info("video upload error retrying.")
134
  select_file_button = page.frame_locator(Tk_Locator.tk_iframe).locator('button[aria-label="Select file"]')
135
  async with page.expect_file_chooser() as fc_info:
136
  await select_file_button.click()
 
144
  page = await context.new_page()
145
 
146
  await page.goto("https://www.tiktok.com/creator-center/upload")
147
+ tiktok_logger.info(f'[+]Uploading-------{self.title}.mp4')
148
 
149
  await page.wait_for_url("https://www.tiktok.com/tiktokstudio/upload", timeout=10000)
150
  await page.wait_for_selector('iframe[data-tt="Upload_index_iframe"]')
 
166
  await self.click_publish(page)
167
 
168
  await context.storage_state(path=f"{self.account_file}") # save cookie
169
+ tiktok_logger.info(' [-] update cookie!')
170
  await asyncio.sleep(2) # close delay for look the video status
171
  # close all
172
  await context.close()
 
195
 
196
  # tag part
197
  for index, tag in enumerate(self.tags, start=1):
198
+ tiktok_logger.info("Setting the %s tag" % index)
199
  await page.keyboard.press("End")
200
  await page.wait_for_timeout(1000) # 等待1秒
201
  await page.keyboard.insert_text("#" + tag + " ")
 
214
  await publish_button.click()
215
 
216
  await page.frame_locator(Tk_Locator.tk_iframe).locator(success_flag_div).wait_for(state="visible", timeout=1500)
217
+ tiktok_logger.success(" [-] video published success")
218
  break
219
  except Exception as e:
220
  if await page.frame_locator(Tk_Locator.tk_iframe).locator(success_flag_div).count():
221
+ tiktok_logger.success(" [-]video published success")
222
  break
223
  else:
224
+ tiktok_logger.exception(f" [-] Exception: {e}")
225
+ tiktok_logger.info(" [-] video publishing")
226
  await page.screenshot(full_page=True)
227
  await asyncio.sleep(0.5)
228
 
 
230
  while True:
231
  try:
232
  if await page.frame_locator(Tk_Locator.tk_iframe).locator('div.btn-post > button').get_attribute("disabled") is None:
233
+ tiktok_logger.info(" [-]video uploaded.")
234
  break
235
  else:
236
+ tiktok_logger.info(" [-] video uploading...")
237
  await asyncio.sleep(2)
238
  if await page.frame_locator(Tk_Locator.tk_iframe).locator('button[aria-label="Select file"]').count():
239
+ tiktok_logger.info(" [-] found some error while uploading now retry...")
240
  await self.handle_upload_error(page)
241
  except:
242
+ tiktok_logger.info(" [-] video uploading...")
243
  await asyncio.sleep(2)
244
 
245
  async def main(self):
utils/log.py ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pathlib import Path
2
+ from sys import stdout
3
+ from loguru import logger
4
+
5
+ from conf import BASE_DIR
6
+
7
+
8
+ def log_formatter(record: dict) -> str:
9
+ """
10
+ Formatter for log records.
11
+ :param dict record: Log object containing log metadata & message.
12
+ :returns: str
13
+ """
14
+ colors = {
15
+ "TRACE": "#cfe2f3",
16
+ "INFO": "#9cbfdd",
17
+ "DEBUG": "#8598ea",
18
+ "WARNING": "#dcad5a",
19
+ "SUCCESS": "#3dd08d",
20
+ "ERROR": "#ae2c2c"
21
+ }
22
+ color = colors.get(record["level"].name, "#b3cfe7")
23
+ return f"<fg #70acde>{{time:YYYY-MM-DD HH:mm:ss}}</fg #70acde> | <fg {color}>{{level}}</fg {color}>: <light-white>{{message}}</light-white>\n"
24
+
25
+
26
+ def create_logger(log_name: str, file_path: str):
27
+ """
28
+ Create custom logger for different business modules.
29
+ :param str log_name: name of log
30
+ :param str file_path: Optional path to log file
31
+ :returns: Configured logger
32
+ """
33
+ def filter_record(record):
34
+ return record["extra"].get("business_name") == log_name
35
+
36
+ Path(BASE_DIR / file_path).parent.mkdir(exist_ok=True)
37
+ logger.add(Path(BASE_DIR / file_path), filter=filter_record, level="INFO", rotation="10 MB", retention="10 days", backtrace=True, diagnose=True)
38
+ return logger.bind(business_name=log_name)
39
+
40
+
41
+ # Remove all existing handlers
42
+ logger.remove()
43
+ # Add a standard console handler
44
+ logger.add(stdout, colorize=True, format=log_formatter)
45
+
46
+ douyin_logger = create_logger('douyin', 'logs/douyin.log')
47
+ tencent_logger = create_logger('tencent', 'logs/tencent.log')
48
+ xhs_logger = create_logger('xhs', 'logs/xhs.log')
49
+ tiktok_logger = create_logger('tiktok', 'logs/tiktok.log')
50
+ bilibili_logger = create_logger('bilibili', 'logs/bilibili.log')
xhs_uploader/cdn.jsdelivr.net_gh_requireCool_stealth.min.js_stealth.min.js DELETED
The diff for this file is too large to render. See raw diff