博客仅供学习研究特别声明
特别声明:本博客的所有源码和内容均仅供学习研究,严禁用于包括但不限于商业谋利、破坏系统、盗取个人信息等不良不法行为,违反此声明使用所产生的一切后果均由违反声明使用者承担。
博主有话说:博客的所有源码和内容均仅供学习研究,若有问题请通过 CSDN 私信博主。本博客的所有源码和内容均仅供学习研究,严禁用于包括但不限于商业谋利、破坏系统、盗取个人信息等不良不法行为,违反此声明使用所产生的一切后果均由违反声明使用者承担。
登录直播中控台
如何进行获取小红书直播间互动消息,我们可以通过登录小红书直播管理平台网站,打开小红书直播中控台页面,在直播中控台【实时互动】获取互动消息。
直播中控台地址:https://redlive.xiaohongshu.com/live_center_control
通过小红书官方的直播助手开启直播,当然同样可以使用手机小红书APP进行直播,都能在小红书直播中控台【实时互动】显示直播间互动消息。
longlink websocket 数据帧
直播间 websocket 连接
通过 开启F12 打开【开发者工具】 ,选择【网络】过滤【WS】,然后进行刷新页面,查看包含 longlink websocket 连接。
安装 pyppeteer
Pyppeteer 是一个 Python 库,提供对 Puppeteer 的 Python 封装。Puppeteer 本身是一个 Node.js 库,用于控制 Chrome 或 Chromium 浏览器,尤其擅长用于自动化浏览器操作,例如爬虫、网页截屏、页面生成 PDF、测试和爬取动态生成的内容等。
pip install pyppeteer
peteer 是一个非常强大的工具,特别适合用在需要处理 JavaScript 渲染内容的网页自动化场景中。它提供了一个 Pythonic 的接口来访问 Puppeteer 的功能,能够帮助开发者高效地进行浏览器自动化和网页数据抓取。
监听直播间 websocket 数据帧
import asyncio
from pyppeteer import launch
executable_path = r'C:\Program Files\Google\Chrome\Application\chrome.exe'
stop_listening = False
async def listen_debugger():
user_data_dir = r'UserData'
browser = await launch(executablePath=executable_path, headless=False, userDataDir=user_data_dir)
page = await browser.newPage()
session = await page.target.createCDPSession()
await session.send('Network.enable')
def on_request(request):
try:
print("Request:", request)
except Exception as e:
print(f"Error while processing request: {e}")
session.on('Network.webSocketFrameReceived', on_request)
await page.goto('https://redlive.xiaohongshu.com/live_center_control')
await page.waitForSelector('body')
task = asyncio.create_task(wait_for_condition(stop_listening))
await task
print("Condition met, closing browser...")
await browser.close()
async def wait_for_condition(stop_listening):
while not stop_listening:
await asyncio.sleep(1)
asyncio.run(listen_debugger())
启动浏览器自动打开 https://redlive.xiaohongshu.com/live_center_control
特别注意:启动脚本,chrome 浏览器自动打开直播中控台网页,显示登录验证表单,需要进行直播账号登录操作。直接进行登录即可,chrome 浏览器自动保存登录 cookie 信息,后续启动脚本打开直播中控台网页无需进行登录验证。
Python console 控制台
弹幕评论消息数据帧
payloadData 是指消息体实际数据内容。小红书直播间 websocket 互动数据 payloadData 数据帧 JSON 结构包含了两部分:header 和 body,分别是消息的元数据和实际的内容。
数据帧 header 数据说明
{
"type": 4,
"domain": "red",
"seq": 29,
"qos": 1,
"bizId": 4,
"contentType": "json"
}
type: 表示消息类型,通常用于标识消息的种类。
domain: 表示消息所域名 IP 信息。
seq: 消息的序列号(跟踪消息顺序)。
qos: 表示消息的 QoS [Quality of Service 服务质量](通常用于控制消息的传递保障)。
bizId: 业务标识符,通常用于区分不同的业务场景或模块。
contentType: 表示消息体的内容格式是 JSON。
数据帧 body 数据说明
{
"uuid": "e5e44db0-2a15-416f-ac12-5d17e686c36d",
"msgId": "1182340023343104000",
"command": 1,
"roomId": "*****",
"roomType": "LIVE",
"priority": 2,
"customData": "······目标数据",
"ts": 1733498228438
}
弹幕评论消息 customData 解析
"customData":"{\"type\":\"text\",\"current_time\":1733498228378,\"source\":\"search_onebox\",\"commentId\":\"7445318192825583302\",\"profile\":{\"avatar\":\"https://sns-avatar-qc.xhscdn.com/avatar/645b809d1b0ee4025dc47735.jpg?imageView2/2/w/80/format/jpg\",\"nickname\":\"子夜吴歌\",\"role\":0,\"user_id\":\"67530258000000001c01a291\"},\"desc\":\"helloworld\"}","ts":1733498228438}
其中 customData 数据是 JSON 字符串,需要通过 json.loads 解析 python dcit 格式。其中 customData 包含 type 属性,当 type == ‘text’ 时候,则是弹幕评论消息。
数据帧 customData 类型
refresh、letter_refresh:刷新事件类型
text:弹幕评论消息事件类型
audience_join、audience_join_v2:用户访问直播间事件类型
gift_dock_and_effect、gift_settle、gift_comment:礼物消息事件类型
······
具体解析待更新···
常见消息事件监听
详细源码
import asyncio
import json
from pyppeteer import launch
executable_path = r'C:\Program Files\Google\Chrome\Application\chrome.exe'
stop_listening = False
async def listen_debugger():
user_data_dir = r'UserData'
browser = await launch(executablePath=r'C:\Program Files\Google\Chrome\Application\chrome.exe',
headless=False, userDataDir=user_data_dir)
page = await browser.newPage()
session = await page.target.createCDPSession()
await session.send('Network.enable')
def on_request(request):
try:
if 'response' in request and 'payloadData' in request['response']:
data = json.loads(request['response']['payloadData'])
if 'type' in data['header'] and data['header']['type'] == 4:
customData = data['body']['customData']
customData = json.loads(customData)
if customData['type'] == "text":
print(f"[弹幕事件][{customData['profile']['nickname']}]: {customData['desc']}")
if customData['type'] == "audience_join":
print(f"[访问事件][{customData['profile']['nickname']}]: 访问直播间")
if customData['type'] == "follow_emcee":
print(f"[关注事件][{customData['profile']['nickname']}]: 关注了主播")
except Exception as e:
print(f"Error while processing request: {e}")
print("Request:", request)
session.on('Network.webSocketFrameReceived', on_request)
await page.goto('https://redlive.xiaohongshu.com/live_center_control')
await page.waitForSelector('body')
task = asyncio.create_task(wait_for_condition(stop_listening))
await task
print("Condition met, closing browser...")
await browser.close()
async def wait_for_condition(stop_listening):
while not stop_listening:
await asyncio.sleep(1)
asyncio.run(listen_debugger())
运行截图
直播间 sendMessage
小红书直播平台直播中控台随便评消息,调试网络数据窗口出现 send_message 请求。说明主播主动评论消息是基于 https 请求。
请求体是 json 格式 {room_id: “直播间 ID”, comment: “helloworld”}
读取 sendMessage Authorization
Authorization 是一个 HTTP 请求头,用于向服务器提供访问权限的凭证。它通常用于身份验证(authentication)和授权(authorization)过程,确保只有经过认证和授权的用户能够访问资源。
缺失登录凭证常见问题
请求失败,状态码: 401
响应内容: {"code":-13000,"success":false,"msg":"缺失登录凭证, 请重新登录","data":{}}
缺失登录凭证解决方案
想要实现自动评论消息,需要我们进行读取直播管理平台 cookie 信息,读取请求头 authorization 信息,即可通过 requests.post 评论信息。
详细源码
import random
import time
import requests
import json
from datetime import datetime
session = requests.Session()
cookies = {
'abRequestId': '*****',
'webBuild': '*****',
'a1': '*****',
'webId': '*****',
'gid': '*****',
'web_session': '*****',
'x-user-id-creator.xiaohongshu.com': '*****',
'customerClientId': '*****',
'access-token-creator.xiaohongshu.com': '*****',
'galaxy_creator_session_id': '*****',
'galaxy.creator.beaker.session.id': '*****',
'unread': '*****',
'xsecappid': '*****',
'customer-sso-sid': '*****',
'x-user-id-redlive.xiaohongshu.com': '*****',
'access-token-redlive.xiaohongshu.com': '*****',
'acw_tc': '*****',
'websectiga': '*****',
'sec_poison_id': '*****'
}
session.cookies.update(cookies)
url = 'https://live-assistant.xiaohongshu.com/api/sns/red/live/web_api/sns/v1/live/interaction/send_comment'
headers = {
'Content-Type': 'application/json; charset=utf-8',
'authorization': '*****'
}
room_id = "*****"
def send_message(comment: str, room_id: str):
data = {
'comment': comment,
'room_id': room_id,
}
response = session.post(url, headers=headers, json=data)
if response.status_code == 200:
response_data = response.json()
now = datetime.now()
formatted_now = now.strftime("%Y-%m-%d %H:%M:%S")
print(f"[时间:{formatted_now}][内容:{comment}]")
else:
print('请求失败,状态码:', response.status_code)
print('响应内容:', response.text)
定时循环评论消息案例
通过 sendMessage 函数我们能自动化评论消息内容,举例每隔 5 s 随机评论中国古诗词。
import random
import time
import requests
import json
from datetime import datetime
session = requests.Session()
cookies = {
'abRequestId': '*****',
'webBuild': '*****',
'a1': '*****',
'webId': '*****',
'gid': '*****',
'web_session': '*****',
'x-user-id-creator.xiaohongshu.com': '*****',
'customerClientId': '*****',
'access-token-creator.xiaohongshu.com': '*****',
'galaxy_creator_session_id': '*****',
'galaxy.creator.beaker.session.id': '*****',
'unread': '*****',
'xsecappid': '*****',
'customer-sso-sid': '*****',
'x-user-id-redlive.xiaohongshu.com': '*****',
'access-token-redlive.xiaohongshu.com': '*****',
'acw_tc': '*****',
'websectiga': '*****',
'sec_poison_id': '*****'
}
session.cookies.update(cookies)
url = 'https://live-assistant.xiaohongshu.com/api/sns/red/live/web_api/sns/v1/live/interaction/send_comment'
headers = {
'Content-Type': 'application/json; charset=utf-8',
'authorization': '*****'
}
room_id = "直播间 ID"
def send_message(comment: str, room_id: str):
data = {
'comment': comment,
'room_id': room_id,
}
response = session.post(url, headers=headers, json=data)
if response.status_code == 200:
response_data = response.json()
now = datetime.now()
formatted_now = now.strftime("%Y-%m-%d %H:%M:%S")
print(f"[时间:{formatted_now}][内容:{comment}]")
else:
print('请求失败,状态码:', response.status_code)
print('响应内容:', response.text)
love_poems = [
"相思相见知何日?此时此夜难为情。",
"曾经沧海难为水,除却巫山不是云。",
"取次花丛懒回顾,半缘修道半缘君。",
"在天愿作比翼鸟,在地愿为连理枝。",
"天长地久有时尽,此恨绵绵无绝期。",
"身无彩凤双飞翼,心有灵犀一点通。",
"相见时难别亦难,东风无力百花残。",
"两情若是久长时,又岂在朝朝暮暮。",
"愿我如星君如月,夜夜流光相皎洁。",
"还君明珠双泪垂,恨不相逢未嫁时。",
"此情可待成追忆,只是当时已惘然。"
]
for _ in range(1000):
random_poem = random.choice(love_poems)
send_message(random_poem, room_id)
time.sleep(5)
运行截图