QQ空间协议发送|删除说说—Python
QQ空间协议发|删说说实现,可用来批量发送说说以及批量删除说说
QQ空间协议——说说篇
本专栏包含QQ空间协议登录、点赞、评论、访客、发说说等
看本文章之前,需要先了解QQ空间协议的登录
文章结尾附Python代码
QQ空间协议账号密码登录
QQ空间扫码登录协议实现
目录
一、QQ空间抓包
1.1发说说包
1.2删说说包
1.3tid获取包
二、g_tk算法
三、Python代码实现及测试结果
3.1g_tk算法
3.2发送说说包代码
3.3获取tid包代码
3.4删除说说代码
一、QQ空间抓包
1.1发说说包
可以抓到POST请求的数据包
https://user.qzone.qq.com/proxy/domain/taotao.qzone.qq.com/cgi-bin/emotion_cgi_publish_v6?&g_tk=492549294
请求表单数据:syn_tweet_verson=1¶mstr=1&pic_template=&richtype=&richval=&special_url=&subrichtype=&who=1&con=helloworld&feedversion=1&ver=1&ugc_right=1&to_sign=0&hostuin=3592795816&code_version=1&format=fs&qzreferrer=https%3A%2F%2Fuser.qzone.qq.com%2F3592795816
g_tk——通过登录Cookie的p_skey计算获得 (可以参考我的QQ空间点赞的文章)
con——发送的说说内容
hostuin——登录的QQ
注意把qzreferer中链接后面的QQ也替换成登录的QQ
注意这个包的响应是gzip,使用Java的话需要进行处理,不然没法查看响应内容Python则直接正常respons.content即可
1.2删说说包
POST请求 https://user.qzone.qq.com/proxy/domain/taotao.qzone.qq.com/cgi-bin/emotion_cgi_delete_v6?=&g_tk=912755888
原始表单数据hostuin=3592795816&tid=a8b625d6e16ded6685200b00&t1_source=1&code_version=1&format=fs&qzreferrer=https%3A%2F%2Fuser.qzone.qq.com%2F3592795816%2F311
{ "hostuin": "3592795816", "tid": "a8b625d6e16ded6685200b00", "t1_source": "1", "code_version": "1", "format": "fs", "qzreferrer": "https://user.qzone.qq.com/3592795816/311" }
抓包响应结果
hostuin——登录的QQ
tid——删除的说说的id
1.3tid获取包
GET请求 https://user.qzone.qq.com/proxy/domain/taotao.qq.com/cgi-bin/emotion_cgi_msglist_v6?uin=3592795816&ftype=0&sort=0&pos=0&num=20&replynum=100&g_tk=912755888&callback=_preloadCallback&code_version=1&format=jsonp&need_private_comment=1
可以一次看到最新的20条说说,将object展开后即可看到tid、说说的内容、发布时间等
可以通过循环GET这个包获取tid,然后删除,达到批量删除说说的效果
uin——登录的QQ
g_tk
二、g_tk算法
简单跟栈,搜索g_tk即可在js中找到g_tk的算法
三、Python代码实现及测试结果
3.1g_tk算法
def get_tk(skey):
hash_value = 5381
for char in skey:
hash_value += (hash_value << 5) + ord(char)
return str(hash_value & 2147483647)
print(get_tk('p_skey'))
可以看到我抓包时的
g_tk=492549294
p_skey=XbZzWNj8nu9JLikYiyGQm7wE0GBM2meSqumv56gQw7E_
以下是代码测试运行结果,可以发现成功得到g_tk
3.2发送说说包代码
def send_message(msg, uin, tk, cookie):
try:
base_url = "https://user.qzone.qq.com/proxy/domain/taotao.qzone.qq.com/cgi-bin/emotion_cgi_publish_v6"
url = f"{base_url}?g_tk={tk}"
headers = {
"Host": "user.qzone.qq.com",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
"Accept-Encoding": "gzip, deflate, br",
"Connection": "keep-alive",
"Cache-Control": "no-cache",
"Origin": "https://user.qzone.qq.com",
"Content-Type": "application/x-www-form-urlencoded",
"Sec-Fetch-Dest": "iframe",
"Sec-Fetch-Mode": "navigate",
"Upgrade-Insecure-Requests": "1",
"Sec-Fetch-Site": "same-origin",
"Cookie": cookie
}
params = {
"qzreferrer": f"https://user.qzone.qq.com/{uin}",
"syn_tweet_verson": "1",
"paramstr": "1",
"pic_template": "",
"richtype": "",
"richval": "",
"special_url": "",
"subrichtype": "",
"who": "1",
"con": f"123{msg}",
"feedversion": "1",
"ver": "1",
"ugc_right": "1",
"to_sign": "0",
"hostuin": uin,
"code_version": "1",
"format": "fs"
}
encoded_data = urllib.parse.urlencode(params)
# 发送 POST 请求
response = requests.post(url, headers=headers, data=encoded_data)
print(response.content)
except Exception as e:
print(f"Error: {e}")
以下为代码测试结果,可以看到成功发送说说,响应内容太多,只展示一部分
3.3获取tid包代码
def get_qzone_data(cookie, uin, g_tk):
url = f"https://user.qzone.qq.com/proxy/domain/taotao.qq.com/cgi-bin/emotion_cgi_msglist_v6?uin={uin}&ftype=0&sort=0&pos=0&num=20&replynum=100&g_tk={g_tk}&callback=_preloadCallback&code_version=1&format=jsonp&need_private_comment=1"
# 请求头
headers = {
"Host": "user.qzone.qq.com",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0",
"Accept": "*/*",
"Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
"Accept-Encoding": "gzip, deflate, br, zstd",
"Connection": "keep-alive",
"Referer": f"https://user.qzone.qq.com/{uin}/311",
"Sec-Fetch-Dest": "script",
"Sec-Fetch-Mode": "no-cors",
"Sec-Fetch-Site": "same-origin",
"Pragma": "no-cache",
"Cache-Control": "no-cache",
"TE": "trailers",
"Cookie": cookie
}
try:
response = requests.get(url, headers=headers)
if response.status_code == 200:
return response.text
else:
return f"请求失败,状态码: {response.status_code}"
except Exception as e:
return f"发生错误: {str(e)}"
3.4删除说说代码
def post_delete_art(cookie, g_tk, hostuin, tid):
url = f"https://user.qzone.qq.com/proxy/domain/taotao.qzone.qq.com/cgi-bin/emotion_cgi_delete_v6?=&g_tk={g_tk}"
data = {
"hostuin": hostuin,
"tid": tid,
"t1_source": "1",
"code_version": "1",
"format": "fs",
"qzreferrer": f"https://user.qzone.qq.com/{hostuin}/311"
}
headers = {
"Host": "user.qzone.qq.com",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0",
"Accept": "*/*",
"Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
"Accept-Encoding": "gzip, deflate, br, zstd",
"Content-Type": "application/x-www-form-urlencoded",
"Connection": "keep-alive",
"Referer": f"https://user.qzone.qq.com/{hostuin}/311",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "no-cors",
"Sec-Fetch-Site": "same-origin",
"Pragma": "no-cache",
"Cache-Control": "no-cache",
"Cookie": cookie
}
try:
# 发送 POST 请求
response = requests.post(url, headers=headers, data=data)
if response.status_code == 200:
return response.text
else:
return f"请求失败,状态码: {response.status_code}"
except Exception as e:
return f"发生错误: {str(e)}"