一、功能
问:要实现每天自动发送头像帖子的小红书账号,总(lǒng)共分几步?
答:总(lǒng)共分三步。第一步生成头像,第二步发布帖子,第三步定时每天执行。
这个精美头像是博主最近搭的小红书账号,可以点击查看一下。
二、实现流程
1. 文生图功能,保存到本地
实现逻辑:本文采用Coze搭建机器人调用通义万相的api,这样没有生成图片额度限制。Coze搭建的机器人支持通过http方式的调用【API 介绍】,可以供node服务调用。可以将扣子工作流添加到自己的机器人。
工作流的功能,根据传入的信息,生成图片链接、帖子标题、帖子详情,将这些信息返回。 通过http调用,将文案保存在本地的json中,图片下载到本地,以供后续自动发帖时使用,以下是Coze接口返回的数据格式。
{
"articleContent": "家人们,今天给大家分享一组超级可爱的小狗头像!🐕 这只小狗简直萌化了我的心,金黄的毛色,圆溜溜的眼睛,还有那耷拉着的耳朵,太让人喜欢啦!😘 用这样可爱的小狗做头像,感觉每天心情都会变好呢!💕 希望你们也能喜欢哦!💗 #小狗头像 #可爱 #头像分享",
"articleTitle": "💖可爱小狗头像分享💖",
"output": [
"https://lf-bot-studio-plugin-resource.coze.cn/obj/bot-studio-platform-plugin-tos/artist/image/4ffe829f90d14c55a48d1f2168433e71.png",
"https://lf-bot-studio-plugin-resource.coze.cn/obj/bot-studio-platform-plugin-tos/artist/image/9ff346721d6e44b7a1bc1e0a523fd3d3.png",
"https://lf-bot-studio-plugin-resource.coze.cn/obj/bot-studio-platform-plugin-tos/artist/image/a1dcddac8f894ab799b999f67546346e.png",
"https://lf-bot-studio-plugin-resource.coze.cn/obj/bot-studio-platform-plugin-tos/artist/image/7c98e086132a4b3f9c738717f9cd6387.png"
]
}
2、利用puppeteer发布帖子
实现逻辑:开启无头浏览器,模拟用户点击,选择图片,输入标题、描述、话题然后自动点击发送按钮。关键代码如下:
// auto_upload.js
// 需要替换为自己的cookie
const cookies = {
"abRequestId": "",
"a1": "",
"webId": "",
"gid": "",
"web_session": "",
"galaxy_creator_session_id": "",
"galaxy.creator.beaker.session.id": "",
"xsecappid": "",
"acw_tc": "",
"websectiga": "",
"sec_poison_id": ""
}
// 设置小红书cookie
async function xiaohongshu_login(page) {
const tempCookies = await page.cookies()
console.log(tempCookies)
// 先清除cookie再设置
for(var i = 0; i < tempCookies.length; i++) {
await page.deleteCookie(tempCookies[i])
}
for(var i in cookies) {
await page.setCookie({
name: i,
value: cookies[i],
domain: '.xiaohongshu.com', // 必须设置domain,否则会有多个不同域名的cookie
})
}
}
const articleInfo = {
"articleContent": "宝子们,今天给大家分享一组超级美的中国画风格的 AI 头像!这组头像真的是美到让人惊艳,每一个细节都充满了艺术感。女子的古装造型、手中的折扇,还有那背后的山水画卷,仿佛让人穿越回了古代。面部的温婉优雅表情,以及随风飘动的发丝,都让人陶醉其中。希望大家会喜欢这组头像!",
"articleTitle": "绝美国画风 AI 头像分享",
"output": [
"https://lf-bot-studio-plugin-resource.coze.cn/obj/bot-studio-platform-plugin-tos/artist/image/f9dd8cbc688641769db38da7c5a23fab.png",
"https://lf-bot-studio-plugin-resource.coze.cn/obj/bot-studio-platform-plugin-tos/artist/image/c4ab0700d81c426f80d7109690bc7147.png",
"https://lf-bot-studio-plugin-resource.coze.cn/obj/bot-studio-platform-plugin-tos/artist/image/d46a1be79a8b46f4b7d4e59d2ad7c18c.png",
"https://lf-bot-studio-plugin-resource.coze.cn/obj/bot-studio-platform-plugin-tos/artist/image/9ec6ddd5c0db478a9a372a9f9de16b67.png"
],
"localPaths": [ //上传的图片地址,需要替换
"E:\\workspace\\xhs_auto_upload\\img\\20240709\\images0.png",
"E:\\workspace\\xhs_auto_upload\\img\\20240709\\images1.png",
"E:\\workspace\\xhs_auto_upload\\img\\20240709\\images2.png",
"E:\\workspace\\xhs_auto_upload\\img\\20240709\\images3.png"
]
}
// 自执行函数
(async () => {
const browser = await puppeteer.launch({
headless: false
});
const page = await browser.newPage();
await xiaohongshu_login(page)
await await page.goto(PAGE_URL);
await page.setViewport({
width: 2280,
height: 3200
});
await delay(3000)
// 点击上传图文
const btn = await page.$('xpath/.//*[@id="web"]/div/div/div[1]/div[2]')
console.log("btn", btn)
await btn.click()
// 上传单张图片
// const uploadBtn = await page.$('xpath/.//*[@id="web"]/div/div/div[2]/div[1]/div/input')
// await uploadBtn.uploadFile('./img/20240620-151817.jpeg')
// 上传多张图片
const [fileChooser] = await Promise.all([
page.waitForFileChooser(),
page.click('xpath/.//*[@id="web"]/div/div/div[2]/div[1]/div/input')
]).catch(async (e) => {
console.log(e)
});
fileChooser.accept(articleInfo.localPaths)
await delay(2000)
// 设置文章标题、文章内容
await page.type('xpath/.//*[contains(@class,"titleInput")]//input', articleInfo.articleTitle)
await page.type('xpath/.//*[contains(@class,"topic-container")]//p', articleInfo.articleContent)
await delay(2000)
// 添加话题
let topicList = ['#头像', '#微信头像', '#最爱的头像', '#一起换头像把', '#分享头像', '#头像分享', '#头像推荐']
for(var i = 0; i<topicList.length; i++) {
await page.type('xpath/.//*[contains(@class,"topic-container")]//p', topicList[i])
await delay(2000)
const topicItem = await page.$('xpath/.//*[contains(@class, "publish-topic-item")]')
await topicItem.click()
}
// 发布文章
const submitBtn = await page.$('xpath/.//*[text()="发布"]')
await submitBtn.click()
})();
碰到的问题:
- 设置cookie的时候,最初没有设置domain,导致cookie没有生效
- 选择图片时,最初采用input.uploadFile,只能上传一张图片,后续采用别的方式兼容
- 获取input标签,最初采用documnet.querySelectorAll,后续采用了xpath方式,xpath更方便
- 添加话题的时候,话题列表列表在失去焦点的时候就会消失,无法调试。只需要在Console下,用一个计时器
setTimeout(() => { debugger }, 3000)
延时进入断点就好,时长根据页面操作复杂度自行决定,先执行这个计时器,再移到页面中触发事件,弹出临时创建的DOM
3、开启定时任务
系统 | 方案 | 示例 |
---|---|---|
windows | 任务计划程序,有ui界面操作 | 新建.bat文件,新建计划程序定时执行.bat |
mac/linux | crontab | 55 16 * * * /Users/ljp/.nvm/versions/node/v16.14.2/bin/node /Users/ljp/workspace/study/xiaohongshu/auto_upload.js |
CRON 表达式是一个字符串,以 5 个空格隔开,分为 6个域,每一个域代表一个含义。cron语法介绍
:分 小时 日期 月份 星期
。使用crontab -e
编辑定时任务,可以配置MAILTO,定时任务如果执行失败会将日志发送到配置的邮箱。
MAILTO="test@163.com"
55 16 * * * /Users/ljp/.nvm/versions/node/v16.14.2/bin/node /Users/ljp/workspace/study/xiaohongshu/auto_upload.js