使用 Playwright MCP 实现小红书全自动发布的完整流程
本文将为你带来一份零基础的保姆级教程,手把手教你如何利用 Playwright MCP 实现小红书图文的无人值守自动发布。
📝 面试求职: 「面试试题小程序」 ,内容涵盖 测试基础、Linux操作系统、MySQL数据库、Web功能测试、接口测试、APPium移动端测试、Python知识、Selenium自动化测试相关、性能测试、性能测试、计算机网络知识、Jmeter、HR面试,命中率杠杠的。(大家刷起来…)
📝 职场经验干货:
你是否曾为自动化脚本中的小红书登录验证而头疼?是否曾因登录态频繁失效而不得不手动介入,让所谓的“全自动”名存实亡?
Playwright Model Context Protocol (MCP) 的推出,彻底改变了这一局面。它不再是简单的浏览器控制,而是通过直接连接到你已登录的浏览器会话,实现了真正的“无感知”自动化。这意味着,你只需要手动登录一次小红书,之后的发布、互动等所有操作都可以交给脚本,无需再关心复杂的登录验证流程。
本文将为你带来一份零基础的保姆级教程,手把手教你如何利用 Playwright MCP 实现小红书图文的无人值守自动发布。
一、环境准备与配置:打下坚实基础
1.1 安装 Playwright
确保你的 Python 环境在 3.7 以上,然后安装 Playwright:
pip install playwright
playwright install chromium
1.2 安装配置 MCP 服务器
Playwright MCP 需要一个服务器来协调浏览器和你的自动化脚本:
# 通过 npm 全局安装
npm install -g @playwright/mcp
# 或者使用 npx 直接运行
npx @playwright/mcp
1.3 安装浏览器扩展
这是实现会话复用的关键步骤:
-
下载 Playwright MCP Chrome 扩展(ZIP 文件)
-
打开 Chrome,进入
chrome://extensions/
-
开启“开发者模式”
-
点击“加载已解压的扩展程序”,选择解压后的文件夹
-
完成安装后,记得在扩展管理界面启用它
二、连接已登录的浏览器会话
2.1 启动浏览器并手动登录
首先,你需要让浏览器以调试模式运行:
# Windows
chrome.exe --remote-debugging-port=9222
# macOS
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222
然后在打开的浏览器中手动登录小红书账号,完成所有必要的验证步骤。
2.2 编写连接代码
创建一个 Python 文件,写入以下代码来连接已登录的浏览器:
import asyncio
from playwright.async_api import async_playwright
asyncdef connect_to_logged_in_browser():
asyncwith async_playwright() as p:
# 连接到正在运行的浏览器实例
browser = await p.chromium.connect_over_cdp("http://localhost:9222")
# 获取默认的浏览器上下文
default_context = browser.contexts[0]
# 使用现有的页面或创建新页面
if default_context.pages:
page = default_context.pages[0]
else:
page = await default_context.new_page()
# 检查是否已登录
await page.goto('https://www.xiaohongshu.com')
try:
# 等待用户头像或其他登录后可见元素出现
await page.wait_for_selector('[data-testid="user-avatar"]', timeout=5000)
print("✅ 检测到已登录状态")
return page
except:
print("❌ 未检测到登录状态,请先手动登录")
returnNone
# 测试连接
asyncdef test_connection():
page = await connect_to_logged_in_browser()
if page:
await page.screenshot(path='login_status.png')
print("截图已保存,请查看登录状态")
await browser.disconnect()
asyncio.run(test_connection())
三、完整的小红书图文发布脚本
以下是一个完整的自动化发布脚本,包含了异常处理和详细注释:
import asyncio
from playwright.async_api import async_playwright
import random
import os
class XiaohongshuAutoPublisher:
def __init__(self):
self.browser = None
self.page = None
asyncdef init_browser(self):
"""初始化浏览器连接"""
try:
playwright = await async_playwright().start()
self.browser = await playwright.chromium.connect_over_cdp(
"http://localhost:9222"
)
self.context = self.browser.contexts[0]
self.page = self.context.pages[0] if self.context.pages elseawait self.context.new_page()
# 设置超时时间
self.page.set_default_timeout(30000)
returnTrue
except Exception as e:
print(f"❌ 浏览器连接失败: {e}")
returnFalse
asyncdef goto_create_page(self):
"""导航到创作中心"""
try:
await self.page.goto('https://www.xiaohongshu.com/create', waitUntil='networkidle')
# 等待发布界面加载完成
await self.page.wait_for_selector('div[contenteditable="true"]', timeout=15000)
print("✅ 成功进入创作中心")
returnTrue
except Exception as e:
print(f"❌ 进入创作中心失败: {e}")
await self.page.screenshot(path='error_create_page.png')
returnFalse
asyncdef upload_images(self, image_paths):
"""上传图片"""
try:
# 等待文件上传输入框
await self.page.wait_for_selector('input[type="file"]', timeout=10000)
# 获取文件上传句柄
file_input = await self.page.query_selector('input[type="file"]')
if isinstance(image_paths, str):
image_paths = [image_paths]
await file_input.set_input_files(image_paths)
print("✅ 图片上传成功")
# 等待图片处理完成
await self.page.wait_for_selector('img[src*="upload"]', timeout=30000)
await asyncio.sleep(2) # 额外等待确保完全加载
returnTrue
except Exception as e:
print(f"❌ 图片上传失败: {e}")
await self.page.screenshot(path='error_upload.png')
returnFalse
asyncdef input_content(self, content, tags):
"""输入正文内容和标签"""
try:
# 定位正文编辑器
editor = await self.page.wait_for_selector('div[contenteditable="true"]', timeout=10000)
# 清空现有内容
await editor.click(clickCount=3) # 三击全选
await self.page.keyboard.press('Backspace')
# 输入内容
await editor.type(content)
# 添加标签
if tags:
tag_text = ' ' + ' '.join([f'#{tag}'for tag in tags])
await editor.type(tag_text)
print("✅ 内容输入成功")
# 添加随机延迟,模拟人类输入
await asyncio.sleep(random.uniform(1, 3))
returnTrue
except Exception as e:
print(f"❌ 内容输入失败: {e}")
await self.page.screenshot(path='error_content.png')
returnFalse
asyncdef publish(self):
"""执行发布操作"""
try:
# 定位发布按钮
publish_button = await self.page.wait_for_selector('button:has-text("发布")', timeout=10000)
await publish_button.click()
print("✅ 已点击发布按钮")
# 等待发布结果
try:
await self.page.wait_for_selector('text=发布成功', timeout=15000)
print("🎉 发布成功!")
returnTrue
except:
# 检查是否有错误提示
error_element = await self.page.query_selector('text=/发布失败|错误/')
if error_element:
error_text = await error_element.inner_text()
print(f"❌ 发布失败: {error_text}")
else:
print("⚠️ 发布状态未知,请手动确认")
returnFalse
except Exception as e:
print(f"❌ 发布操作失败: {e}")
await self.page.screenshot(path='error_publish.png')
returnFalse
asyncdef run(self, content, image_paths, tags=None):
"""执行完整发布流程"""
ifnotawait self.init_browser():
returnFalse
try:
steps = [
(self.goto_create_page, "进入创作中心"),
(lambda: self.upload_images(image_paths), "上传图片"),
(lambda: self.input_content(content, tags), "输入内容"),
(self.publish, "发布内容")
]
for step_func, step_name in steps:
print(f"▶️ 正在执行: {step_name}")
ifnotawait step_func():
print(f"❌ 流程中断于: {step_name}")
returnFalse
# 步骤间随机延迟
await asyncio.sleep(random.uniform(1, 2))
returnTrue
finally:
if self.browser:
await self.browser.disconnect()
# 使用示例
asyncdef main():
publisher = XiaohongshuAutoPublisher()
# 发布内容配置
content = """
Playwright MCP 真是太强大了!🤖
刚刚用全自动脚本发布了这篇小红书,完全不需要手动登录和验证。
#技术分享 #自动化 #Playwright #小红书运营
"""
image_paths = [
'/path/to/your/image1.jpg',
'/path/to/your/image2.jpg'
]
tags = ['技术分享', '自动化', 'Playwright']
success = await publisher.run(content, image_paths, tags)
if success:
print("🎉 自动化发布流程完成!")
else:
print("❌ 发布流程失败")
if __name__ == "__main__":
asyncio.run(main())
四、高级技巧与最佳实践
4.1 会话保持与状态管理
# 保存浏览器状态,避免重复登录
asyncdef save_browser_state():
asyncwith async_playwright() as p:
browser = await p.chromium.launch(headless=False)
context = await browser.new_context()
page = await context.new_page()
# 手动登录过程...
# 登录成功后保存状态
await context.storage_state(path='xiaohongshu_auth.json')
await browser.close()
# 使用保存的状态
asyncdef use_saved_state():
asyncwith async_playwright() as p:
browser = await p.chromium.launch()
context = await browser.new_context(storage_state='xiaohongshu_auth.json')
page = await context.new_page()
# 现在应该处于已登录状态
4.2 智能元素定位策略
# 使用多种选择器策略提高稳定性
asyncdef smart_click(text):
selectors = [
f'button:has-text("{text}")',
f'div:has-text("{text}")',
f'//*[contains(text(), "{text}")]',
f'[data-testid*="{text.lower()}"]'
]
for selector in selectors:
try:
element = await self.page.wait_for_selector(selector, timeout=2000)
await element.click()
returnTrue
except:
continue
print(f"❌ 找不到文本为 {text} 的元素")
returnFalse
4.3 完整的错误处理与重试机制
async def robust_operation(operation, max_retries=3):
"""带重试机制的操作执行"""
for attempt in range(max_retries):
try:
returnawait operation()
except Exception as e:
if attempt == max_retries - 1:
raise e
print(f"⚠️ 操作失败,第 {attempt + 1} 次重试: {e}")
await asyncio.sleep(2 ** attempt) # 指数退避
# 使用示例
asyncdef safe_publish():
await robust_operation(lambda: self.page.click('button:has-text("发布")'))
五、常见问题与解决方案
5.1 连接被拒绝
问题:无法连接到 http://localhost:9222
解决方案:
-
确保浏览器以调试模式启动
-
检查防火墙设置,确保端口可访问
-
尝试使用不同的端口号
5.2 元素找不到或操作超时
问题:选择器失效或页面加载过慢
解决方案:
-
使用多种选择器策略组合
-
增加等待时间和重试机制
-
添加页面状态检查
5.3 风控检测
问题:操作被限制或账号被暂时封锁
解决方案:
-
添加随机延迟和人类化操作模式
-
避免高频次操作
-
使用多个账号轮换操作
最后: 下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】
更多推荐
所有评论(0)