feat: 增加 xiaohongshu 的登录和发布相关脚本

This commit is contained in:
Edan's Win11
2025-06-03 23:02:47 +08:00
parent 8be9a09432
commit 86fb7f6563
12 changed files with 535 additions and 22 deletions
+26 -12
View File
@@ -71,22 +71,36 @@ async def cookie_auth_ks(account_file):
return True
async def cookie_auth_xhs(account_file):
async with async_playwright() as playwright:
browser = await playwright.chromium.launch(headless=True)
context = await browser.new_context(storage_state=account_file)
context = await set_init_script(context)
# 创建一个新的页面
page = await context.new_page()
# 访问指定的 URL
await page.goto("https://creator.xiaohongshu.com/creator-micro/content/upload")
try:
await page.wait_for_url("https://creator.xiaohongshu.com/creator-micro/content/upload", timeout=5000)
except:
print("[+] 等待5秒 cookie 失效")
await context.close()
await browser.close()
return False
# 2024.06.17 抖音创作者中心改版
if await page.get_by_text('手机号登录').count() or await page.get_by_text('扫码登录').count():
print("[+] 等待5秒 cookie 失效")
return False
else:
print("[+] cookie 有效")
return True
async def check_cookie(type,file_path):
match type:
# 小红书
case 1:
config = configparser.RawConfigParser()
config.read(Path(BASE_DIR / "cookiesFile" / file_path))
cookies = config['account1']['cookies']
xhs_client = XhsClient(cookies, sign=sign_local, timeout=60)
# auth cookie
# 注意:该校验cookie方式可能并没那么准确
try:
xhs_client.get_video_first_frame_image_id("3214")
except:
print("cookie 失效")
return True
return await cookie_auth_xhs(Path(BASE_DIR / "cookiesFile" / file_path))
# 视频号
case 2:
return await cookie_auth_tencent(Path(BASE_DIR / "cookiesFile" / file_path))
@@ -99,5 +113,5 @@ async def check_cookie(type,file_path):
case _:
return False
# a = asyncio.run(check_cookie(4,"3a6cfdc0-3d51-11f0-8507-44e51723d63c.json"))
# a = asyncio.run(check_cookie(1,"3a6cfdc0-3d51-11f0-8507-44e51723d63c.json"))
# print(a)
+74 -3
View File
@@ -217,6 +217,77 @@ async def get_ks_cookie(id,status_queue):
conn.commit()
print("✅ 用户状态已记录")
status_queue.put("200")
#
# a = asyncio.run(douyin_cookie_gen(2,None))
# print(a)
# 小红书登录
async def xiaohongshu_cookie_gen(id,status_queue):
url_changed_event = asyncio.Event()
async def on_url_change():
# 检查是否是主框架的变化
if page.url != original_url:
url_changed_event.set()
async with async_playwright() as playwright:
options = {
'args': [
'--lang en-GB'
],
'headless': False, # Set headless option here
}
# Make sure to run headed.
browser = await playwright.chromium.launch(**options)
# Setup context however you like.
context = await browser.new_context() # Pass any options
context = await set_init_script(context)
# Pause the page, and start recording manually.
page = await context.new_page()
await page.goto("https://creator.xiaohongshu.com/")
await page.locator('img.css-wemwzq').click()
img_locator = page.get_by_role("img").nth(2)
# 获取 src 属性值
src = await img_locator.get_attribute("src")
original_url = page.url
print("✅ 图片地址:", src)
status_queue.put(src)
# 监听页面的 'framenavigated' 事件,只关注主框架的变化
page.on('framenavigated',
lambda frame: asyncio.create_task(on_url_change()) if frame == page.main_frame else None)
try:
# 等待 URL 变化或超时
await asyncio.wait_for(url_changed_event.wait(), timeout=200) # 最多等待 200 秒
print("监听页面跳转成功")
except asyncio.TimeoutError:
status_queue.put("500")
print("监听页面跳转超时")
await page.close()
await context.close()
await browser.close()
return None
uuid_v1 = uuid.uuid1()
print(f"UUID v1: {uuid_v1}")
await context.storage_state(path=Path(BASE_DIR / "cookiesFile" / f"{uuid_v1}.json"))
result = await check_cookie(1, f"{uuid_v1}.json")
if not result:
status_queue.put("500")
await page.close()
await context.close()
await browser.close()
return None
await page.close()
await context.close()
await browser.close()
with sqlite3.connect(Path(BASE_DIR / "db" / "database.db")) as conn:
cursor = conn.cursor()
cursor.execute('''
INSERT INTO user_info (type, filePath, userName, status)
VALUES (?, ?, ?, ?)
''', (1, f"{uuid_v1}.json", id, 1))
conn.commit()
print("✅ 用户状态已记录")
status_queue.put("200")
# a = asyncio.run(xiaohongshu_cookie_gen(4,None))
# print(a)
+18 -2
View File
@@ -5,6 +5,7 @@ from conf import BASE_DIR
from uploader.douyin_uploader.main import DouYinVideo
from uploader.ks_uploader.main import KSVideo
from uploader.tencent_uploader.main import TencentVideo
from uploader.xiaohongshu_uploader.main import XiaoHongShuVideo
from utils.constant import TencentZoneTypes
from utils.files_times import generate_schedule_time_next_day
@@ -65,8 +66,23 @@ def post_video_ks(title,files,tags,account_file,category=TencentZoneTypes.LIFEST
app = KSVideo(title, str(file), tags, publish_datetimes[index], cookie)
asyncio.run(app.main(), debug=False)
# def post_every_type(list):
# for task_dist in list:
def post_video_xhs(title,files,tags,account_file,category=TencentZoneTypes.LIFESTYLE.value,enableTimer=False,videos_per_day = 1, daily_times=None,start_days = 0):
# 生成文件的完整路径
account_file = [Path(BASE_DIR / "cookiesFile" / file) for file in account_file]
files = [Path(BASE_DIR / "videoFile" / file) for file in files]
file_num = len(files)
if enableTimer:
publish_datetimes = generate_schedule_time_next_day(file_num, videos_per_day, daily_times,start_days)
else:
publish_datetimes = 0
for index, file in enumerate(files):
for cookie in account_file:
# 打印视频文件名、标题和 hashtag
print(f"视频文件名:{file}")
print(f"标题:{title}")
print(f"Hashtag:{tags}")
app = XiaoHongShuVideo(title, file, tags, publish_datetimes, cookie)
asyncio.run(app.main(), debug=False)