下载地址:www.pan38.com/yun/share.p… 提取密码:1677
这个抖音批量上传工具包含三个主要文件:主程序、配置文件和工具函数。主程序使用Selenium控制比特浏览器实现自动化上传,配置文件存储各种参数设置,工具函数提供辅助功能。使用时需要安装Selenium库和对应浏览器驱动。
import os
import time
import random
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import NoSuchElementException, TimeoutException
class DouyinUploader:
def __init__(self, profile_path=None):
self.driver = None
self.profile_path = profile_path
self.wait_time = 30
self.video_folder = "videos"
self.captions = ["今天天气真好", "分享美好生活", "记录精彩瞬间", "快乐每一天"]
def init_browser(self):
options = webdriver.ChromeOptions()
if self.profile_path:
options.add_argument(f"user-data-dir={self.profile_path}")
options.add_argument("--disable-notifications")
options.add_argument("--disable-infobars")
options.add_argument("--disable-extensions")
options.add_argument("--disable-gpu")
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
self.driver = webdriver.Chrome(options=options)
self.driver.maximize_window()
def login(self):
self.driver.get("https://www.douyin.com")
time.sleep(5)
try:
login_btn = WebDriverWait(self.driver, self.wait_time).until(
EC.element_to_be_clickable((By.XPATH, "//button[contains(text(),'登录')]"))
)
login_btn.click()
time.sleep(3)
print("请手动扫码登录,登录成功后按回车继续...")
input()
except Exception as e:
print(f"登录异常: {e}")
return False
return True
def upload_video(self, video_path, caption=None):
try:
# 打开上传页面
self.driver.get("https://creator.douyin.com/creator-micro/content/upload")
time.sleep(5)
# 上传视频文件
file_input = WebDriverWait(self.driver, self.wait_time).until(
EC.presence_of_element_located((By.XPATH, "//input[@type='file']"))
)
file_input.send_keys(os.path.abspath(video_path))
print(f"开始上传视频: {video_path}")
# 等待视频处理完成
WebDriverWait(self.driver, 300).until(
EC.invisibility_of_element_located((By.XPATH, "//div[contains(text(),'视频上传中')]"))
)
time.sleep(5)
# 填写描述
if not caption:
caption = random.choice(self.captions)
caption_area = WebDriverWait(self.driver, self.wait_time).until(
EC.presence_of_element_located((By.XPATH, "//textarea[@placeholder='添加描述...']"))
)
caption_area.send_keys(caption)
time.sleep(2)
# 点击发布按钮
publish_btn = WebDriverWait(self.driver, self.wait_time).until(
EC.element_to_be_clickable((By.XPATH, "//button[contains(text(),'发布')]"))
)
publish_btn.click()
# 等待发布完成
WebDriverWait(self.driver, 120).until(
EC.presence_of_element_located((By.XPATH, "//div[contains(text(),'发布成功')]"))
)
print(f"视频发布成功: {video_path}")
time.sleep(5)
return True
except Exception as e:
print(f"上传视频失败: {e}")
return False
def batch_upload(self):
if not os.path.exists(self.video_folder):
print(f"视频文件夹 {self.video_folder} 不存在")
return False
video_files = [f for f in os.listdir(self.video_folder) if f.endswith(('.mp4', '.mov', '.avi'))]
if not video_files:
print(f"视频文件夹 {self.video_folder} 中没有视频文件")
return False
for video_file in video_files:
video_path = os.path.join(self.video_folder, video_file)
success = self.upload_video(video_path)
if not success:
print(f"跳过视频 {video_file}")
continue
# 随机等待一段时间,避免频繁操作
wait_time = random.randint(30, 120)
print(f"等待 {wait_time} 秒后继续...")
time.sleep(wait_time)
return True
def close(self):
if self.driver:
self.driver.quit()
if __name__ == "__main__":
# 配置比特浏览器用户数据路径
bit_profile_path = "/path/to/bitbrowser/profile" # 替换为实际路径
uploader = DouyinUploader(profile_path=bit_profile_path)
try:
uploader.init_browser()
if uploader.login():
uploader.batch_upload()
except Exception as e:
print(f"程序运行异常: {e}")
finally:
uploader.close()
# 抖音账号配置
ACCOUNT = {
"username": "your_username", # 替换为你的抖音账号
"password": "your_password" # 替换为你的密码
}
# 浏览器配置
BROWSER = {
"executable_path": "/path/to/chromedriver", # ChromeDriver路径
"profile_path": "/path/to/bitbrowser/profile", # 比特浏览器用户数据路径
"headless": False # 是否无头模式
}
# 上传配置
UPLOAD = {
"video_folder": "videos", # 视频文件夹
"max_retry": 3, # 最大重试次数
"wait_time": {
"min": 30, # 最小等待时间(秒)
"max": 120 # 最大等待时间(秒)
}
}
# 视频描述
CAPTIONS = [
"记录美好生活",
"分享快乐时光",
"今天也要加油哦",
"生活中的小确幸",
"感谢观看,记得点赞关注"
]
import os
import random
import time
from datetime import datetime
def get_video_files(folder):
"""获取文件夹中的所有视频文件"""
if not os.path.exists(folder):
return []
return [f for f in os.listdir(folder)
if f.lower().endswith(('.mp4', '.mov', '.avi', '.mkv', '.flv'))]
def generate_caption(video_name, custom_captions=None):
"""生成视频描述"""
if custom_captions:
return random.choice(custom_captions)
base_name = os.path.splitext(video_name)[0]
tags = ["#抖音", "#短视频", "#记录生活", "#日常"]
return f"{base_name} {random.choice(tags)}"
def random_sleep(min_time, max_time):
"""随机等待一段时间"""
sleep_time = random.randint(min_time, max_time)
print(f"随机等待 {sleep_time} 秒...")
time.sleep(sleep_time)
def log_message(message, level="INFO"):
"""记录日志信息"""
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print(f"[{timestamp}] [{level}] {message}")
def create_video_folder(folder_name):
"""创建视频文件夹"""
if not os.path.exists(folder_name):
os.makedirs(folder_name)
print(f"创建视频文件夹: {folder_name}")
return folder_name