xhsAutoPublisher/xhs_articlepub.py

154 lines
10 KiB
Python
Raw Normal View History

2025-08-27 09:25:17 +08:00
import selenium
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import json
import base64
class xhsPublisher():
def __init__(self, driver, cookies_path):
self.driver = driver
self.cookies_path = cookies_path
self.cookies = json.loads(open(self.cookies_path, "r").read())
self.load_cookies()
self.WEB_URL = "https://creator.xiaohongshu.com/publish/publish?from=menu"
def load_cookies(self):
for cookie in self.cookies:
# 确保每个cookie都有'sameSite'属性
if True:
# if 'sameSite' not in cookie:
cookie['sameSite'] = 'Strict' # 或者根据需要设置为'Strict'或'None'
self.driver.add_cookie(cookie)
return True
def open_web(self):
self.driver.get(self.WEB_URL)
return True
def select_upload_type(self, upload_type):
## 这里没改好
if upload_type == "image":
# 图文
self.driver.find_element(By.XPATH, "//div[@data-v-16fdb080 and @data-v-a964f0b4 and @class='creator-tab active']").click()
elif upload_type == "video":
# 视频
self.driver.find_element(By.XPATH, "//div[@data-v-7cbccdb2 and @data-v-08fc0cfe and @class='drag-over']").click()
return True
def upload_image(self, image_path):
image_base64 = self.transbase64(image_path)
self.driver.find_element(By.XPATH, "//input[@data-v-4fabe6c5 and @data-v-7cbccdb2-s and @class='upload-input']").send_keys(image_base64)
return True
def upload_video(self, video_path):
video_base64 = self.transbase64(video_path)
self.driver.find_element(By.XPATH, "//input[@data-v-4fabe6c5 and @data-v-7cbccdb2-s and @class='upload-input']").send_keys(video_base64)
return True
def transbase64(self, file_path):
with open(file_path, "rb") as image_file:
return base64.b64encode(image_file.read()).decode('utf-8')
def publish(self, title, content):
self.driver.find_element(By.XPATH, "//input[@class='d-text']").send_keys(title)
self.driver.find_element(By.XPATH, "//div[@class='ql-editor ql-blank']").send_keys(content)
return True
def click_publish(self):
self.driver.find_element(By.XPATH, "//button[@data-v-34b0c0bc and @data-v-9bfbb062 and @data-v-1fed608d-s and @type='button' and @class='d-button d-button-large --size-icon-large --size-text-h6 d-button-with-content --color-static bold --color-bg-fill --color-text-paragraph custom-button red publishBtn' and @data-eaglet-imp='true']").click()
return True
def publish_article(self, title, content, image_path, video_path):
self.select_upload_type("image")
self.upload_image(image_path)
self.publish(title, content)
self.click_publish()
return True
def publish_video(self, title, content, video_path):
self.select_upload_type("video")
self.upload_video(video_path)
self.publish(title, content)
self.click_publish()
return True
def work(self, type, title, content, image_path, video_path):
try:
self.open_web()
self.driver.maximize_window()
self.driver.implicitly_wait(500)
if type == "article":
self.publish_article(title, content, image_path, video_path)
elif type == "video":
self.publish_video(title, content, video_path)
else:
raise ValueError("Invalid type")
self.driver.quit()
except Exception as e:
print(e)
finally:
self.driver.quit()
return True
if __name__ == "__main__":
driver = webdriver.Safari()
# 设置浏览器全屏
driver.maximize_window()
# 设置模拟位置(经度和纬度)
driver.execute_script("navigator.geolocation.getCurrentPosition = function(success) {"
"success({coords: {latitude: 37.7749, longitude: -122.4194}});"
"};")
cookies_path = "/Users/yarrow/Spider/seleniumXH/cookies.json"
cookies = json.loads(open(cookies_path, "r").read())
# print(cookies)
for cookie in cookies:
# 确保每个cookie都有'sameSite'属性
if True:
# if 'sameSite' not in cookie:
cookie['sameSite'] = 'Strict' # 或者根据需要设置为'Strict'或'None'
driver.add_cookie(cookie)
driver.get("https://creator.xiaohongshu.com/publish/publish?from=menu")
# input("press any key to quit")
driver.implicitly_wait(3000)
## 图文
# <div data-v-16fdb080="" data-v-a964f0b4="" class="creator-tab active"><span data-v-16fdb080="" class="title">上传图文</span><div data-v-16fdb080="" class="underline"></div></div>
driver.find_element(By.XPATH, "//div[@data-v-16fdb080 and @data-v-a964f0b4 and @class='creator-tab']").click()
# <input data-v-4fabe6c5="" data-v-7cbccdb2-s="" class="upload-input" type="file" multiple="" accept=".jpg,.jpeg,.png">
# 视频 ## <div data-v-7cbccdb2="" data-v-08fc0cfe="" class="drag-over"><input data-v-08fc0cfe="" data-v-7cbccdb2-s="" class="upload-input" type="file" accept=".mp4,.mov,.flv,.f4v,.mkv,.rm,.rmvb,.m4v,.mpg,.mpeg,.ts"><div data-v-08fc0cfe="" data-v-7cbccdb2-s="" class="wrapper"><img data-v-08fc0cfe="" data-v-7cbccdb2-s="" src="//fe-static.xhscdn.com/formula-static/ugc/public/img/upload-large.e52d3e7.png" class="upload-icon"><p data-v-08fc0cfe="" data-v-7cbccdb2-s="">拖拽视频到此或点击上传</p><button data-v-08fc0cfe="" data-v-7cbccdb2-s="" aria-disabled="false" type="button" class="el-button upload-button" style="--el-button-bg-color: #ff2442; --el-button-text-color: var(--el-color-white); --el-button-border-color: #ff2442; --el-button-hover-bg-color: rgb(255, 102, 123); --el-button-hover-text-color: var(--el-color-white); --el-button-hover-border-color: rgb(255, 102, 123); --el-button-active-bg-color: rgb(208, 33, 57); --el-button-active-border-color: rgb(208, 33, 57);"><!--v-if--><span class="">上传视频</span></button></div></div>
driver.find_element(By.XPATH, "//input[@data-v-4fabe6c5 and @data-v-7cbccdb2-s and @class='upload-input']").send_keys("/Users/yarrow/Spider/cableCar.jpg")
print("send keys /Users/yarrow/Spider/cableCar.jpg")
driver.implicitly_wait(10)
print("wait 10 seconds")
# 标题
# <input class="d-text" type="text" placeholder="填写标题会有更多赞哦~" value="">
driver.find_element(By.XPATH, "//input[@class='d-text']").send_keys("缆车")
print("send keys 缆车")
# 正文
# <div class="ql-editor ql-blank" contenteditable="true" aria-owns="quill-mention-list" data-placeholder="输入正文描述,真诚有价值的分享予人温暖"><p><br></p></div>
driver.find_element(By.XPATH, "//div[@class='ql-editor ql-blank']").send_keys("""缆车 \n
#周末去哪儿玩
""")
print("send keys 缆车")
# 发布
# <button data-v-34b0c0bc="" data-v-9bfbb062="" data-v-1fed608d-s="" type="button" class="d-button d-button-large --size-icon-large --size-text-h6 d-button-with-content --color-static bold --color-bg-fill --color-text-paragraph custom-button red publishBtn" data-impression="{&quot;noteTarget&quot;:{&quot;type&quot;:&quot;NoteTarget&quot;,&quot;value&quot;:{&quot;noteEditSource&quot;:1,&quot;noteType&quot;:1}},&quot;event&quot;:{&quot;type&quot;:&quot;Event&quot;,&quot;value&quot;:{&quot;targetType&quot;:{&quot;type&quot;:&quot;RichTargetType&quot;,&quot;value&quot;:&quot;note_compose_target&quot;},&quot;action&quot;:{&quot;type&quot;:&quot;NormalizedAction&quot;,&quot;value&quot;:&quot;impression&quot;},&quot;pointId&quot;:50979}},&quot;page&quot;:{&quot;type&quot;:&quot;Page&quot;,&quot;value&quot;:{&quot;pageInstance&quot;:{&quot;type&quot;:&quot;PageInstance&quot;,&quot;value&quot;:&quot;creator_service_platform&quot;}}}}" data-eaglet-imp="true"><div class="d-button-content"><!----><span class="d-text --color-static --color-current --size-text-paragraph d-text-nowrap d-text-ellipsis d-text-nowrap" style="text-underline-offset: auto;"><!---->发布<!----><!----><!----></span><!----></div></button>
# <button data-v-34b0c0bc="" data-v-9bfbb062="" data-v-1fed608d-s="" type="button" class="d-button d-button-large --size-icon-large --size-text-h6 d-button-with-content --color-static bold --color-bg-fill --color-text-paragraph custom-button red publishBtn" data-impression="{&quot;noteTarget&quot;:{&quot;type&quot;:&quot;NoteTarget&quot;,&quot;value&quot;:{&quot;noteEditSource&quot;:1,&quot;noteType&quot;:1}},&quot;event&quot;:{&quot;type&quot;:&quot;Event&quot;,&quot;value&quot;:{&quot;targetType&quot;:{&quot;type&quot;:&quot;RichTargetType&quot;,&quot;value&quot;:&quot;note_compose_target&quot;},&quot;action&quot;:{&quot;type&quot;:&quot;NormalizedAction&quot;,&quot;value&quot;:&quot;impression&quot;},&quot;pointId&quot;:50979}},&quot;page&quot;:{&quot;type&quot;:&quot;Page&quot;,&quot;value&quot;:{&quot;pageInstance&quot;:{&quot;type&quot;:&quot;PageInstance&quot;,&quot;value&quot;:&quot;creator_service_platform&quot;}}}}" data-eaglet-imp="true"><div class="d-button-content"><!----><span class="d-text --color-static --color-current --size-text-paragraph d-text-nowrap d-text-ellipsis d-text-nowrap" style="text-underline-offset: auto;"><!---->发布<!----><!----><!----></span><!----></div></button>
# <span class="d-text --color-static --color-current --size-text-paragraph d-text-nowrap d-text-ellipsis d-text-nowrap" style="text-underline-offset: auto;"><!---->发布<!----><!----><!----></span>
driver.find_element(By.XPATH, "//button[@data-v-34b0c0bc and @data-v-9bfbb062 and @data-v-1fed608d-s and @type='button' and @class='d-button d-button-large --size-icon-large --size-text-h6 d-button-with-content --color-static bold --color-bg-fill --color-text-paragraph custom-button red publishBtn' and @data-eaglet-imp='true']").click()
## 找到span内容为发布的
# driver.find_element(By.XPATH, "//span[@class='d-text --color-static --color-current --size-text-paragraph d-text-nowrap d-text-ellipsis d-text-nowrap' and @style='text-underline-offset: auto;']").click()
driver.implicitly_wait(500)
input("press any key to quit")
driver.quit()
## button