快手批量上传视频
本帖最后由 命夜嚣色 于 2021-2-21 20:20 编辑首先我来讲讲过程吧,获取手机号->模拟登录->获取kuaishou.web.cp.api_ph->获取上传token->申请块上传文件->上传文件->文件上传完毕->发布视频
发布视频需要coverKey,fileId,kuaishou.web.cp.api_ph,这三个参数
coverKey和fileId是上传文件完毕时获取到的
kuaishou.web.cp.api_ph是登录时获到的
这个submit就是最后需要访问的也是发布视频
kuaishou.web.cp.api_ph:
首先从拿到kuaishou.web.cp.api.at
然后
因为基础跳的太多,搞了一星期才明白请求POST,GET,JSON,表单数据的请求方法不是一样的
获取上传token:
这个就是
申请块上传文件:
没什么好解释的这里
上传文件:
首先他用的是二进制上传(我找了老半天路径都没找到后来突然悟到)
他每次上传块最大是4194304字节也就是4M(假如视频文件是7M,那就分为两个块上传,假如是4M那就一个块上传)
这就是浏览器显示的请求,当时看见很懵逼
再来看看他POST请求
很长,但很简单
最后这个0就是块文件的第一个文件,这里就不多讲了
文件上传完毕,获取coverKey和fileId:
我估计抖音的也是用的块上传,也是二进制传输文件
整体过程就像是玩解密游戏一样,还是挺有趣的
发布视频参数就都获取完了,也没有什么好讲的了,下面直接发源码
#coding:utf-8
#命夜嚣色
import urllib
import urllib.request
import ssl
import http.cookiejar
import requests,json
import re
import time
import random
import os
from http.cookiejar import MozillaCookieJar
from urllib.request import urlopen
ssl._create_default_https_context=ssl._create_unverified_context
c=http.cookiejar.LWPCookieJar()#生成一个储存cookie的对象
cookie=urllib.request.HTTPCookieProcessor(c)
opener=urllib.request.build_opener(cookie)#把这储存器绑定到opener对象中
urllib.request.install_opener(opener)
定时=1#分钟
header ={
'Referer':'https://cp.kuaishou.com/article/publish/video',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0'
}
def login():
# print("ccccc")
手机号=input('请输入手机号:')
#获取验证码
req=urllib.request.Request('https://id.kuaishou.com/pass/kuaishou/sms/requestMobileCode')
req.headers=header#模拟浏览器
data={
'sid':'kuaishou.web.cp.api',
'type':'53',
'countryCode':'+86',
'phone':手机号,
'ztIdentityVerificationType':"",
'ztIdentityVerificationCheckToken':""
}
data=urllib.parse.urlencode(data).encode('utf-8')
html=opener.open(req,data).read()#html会返回验证码成功或不成功
#print(html)
code=input('请输入验证码:')
#验证 验证码区
req=urllib.request.Request('https://id.kuaishou.com/pass/kuaishou/login/mobileCode')
req.headers=header#模拟浏览器
data={
'countryCode':'+86',
'sid':'kuaishou.web.cp.api',
'createId':'true',
'phone':手机号,
'smsCode':code
}
data=urllib.parse.urlencode(data).encode('utf-8')
html=opener.open(req,data).read()#html会返回验证码成功或不成功
#print(html)
#获取kuaishou.web.cp.api.at
提取字符串=html.decode('utf-8')
# print(re.search('kuaishou.web.cp.api.at',提取字符串).span())
元组= re.search('kuaishou.web.cp.api.at',提取字符串).span()
list_str = list(提取字符串)
for num in range(0,元组+25):
list_str.pop(0)
提取字符串 = ''.join(list_str)
元组= re.search('",',提取字符串).span()
list_str = list(提取字符串)
for num in range(元组,len(list_str)):
list_str.pop(元组)
提取字符串 = ''.join(list_str)
kuaishou_web_cp_api_at=提取字符串
#print(kuaishou_web_cp_api_at)
# print(取第一个数)
# print(type(取第一个数))
# print(type(num))
随机数=random.randint(0,9)
#获取kuaishou.web.cp.api_ph
data={
'authToken':kuaishou_web_cp_api_at,
'sid':'kuaishou.web.cp.api'
}
data=json.dumps(data).encode()
header2 ={
'Connection':'keep-alive',
'Content-Length':len(data),
'EagleEye-pAppName':'e6zufio2qe@6aa9d0be6640ab'+str(随机数),
'EagleEye-SessionID':'stk'+str(随机数)+'Lke6od75zahpCh3pq8nk99qR',
'Pragma':'no-cache',
'Referer':'https://passport.kuaishou.com/account/login/?sid=kuaishou.web.cp.api&redirectURL=https%3A%2F%2Fcp.kuaishou.com%2Fprofile',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0',
}
req=urllib.request.Request('https://passport.kuaishou.com/account/login/api/verifyToken',data=data,method='POST')
req.headers=header2#模拟浏览器
html=opener.open(req,data).read()#html会返回验证码成功或不成功
#print(html)
提取字符串=html.decode('utf-8')
元组= re.search('kuaishou.web.cp.api_ph',提取字符串).span()
list_str = list(提取字符串)
for num in range(0,元组+25):
list_str.pop(0)
提取字符串 = ''.join(list_str)
元组= re.search('",',提取字符串).span()
list_str = list(提取字符串)
for num in range(元组,len(list_str)):
list_str.pop(元组)
提取字符串 = ''.join(list_str)
kuaishou_web_cp_api_ph=提取字符串
#print(kuaishou_web_cp_api_ph)
#html=urlopen(req,data)
# print(c)
# print(len(data))
# print(html.read().decode())
文件个数 = 0
集合=set(())
for root, dirs, files in os.walk(r"."):
# root 表示当前正在访问的文件夹路径
# dirs 表示该文件夹下的子目录名list
# files 表示该文件夹下的文件list
# 遍历文件
for f in files:
字符串=re.search('.mp4',os.path.join(root, f))
if 字符串!=None:
集合.add(os.path.join(root, f))
文件个数 += 1
#print(集合)
#print(os.path.join(root, f))
列表=list(集合)
print('一共有'+str(文件个数)+'个视频')
循环次数=0
while 循环次数<文件个数:
循环次数=循环次数+1
time.sleep(60*定时)#秒
文件名=列表
真与假=True
while 真与假:
元组= re.search(r'\\',文件名)
if 元组==None:
真与假=False
else:
list_str = list(文件名)
for num in range(0,元组.end()):
list_str.pop(0)
文件名 = ''.join(list_str)
print('正在上传'+文件名)
#模拟上传视频
#1.获取上传token
data={
'kuaishou.web.cp.api_ph':kuaishou_web_cp_api_ph,
'uploadType':'1'
}
data=json.dumps(data).encode()
header3 ={
'Connection':'keep-alive',
'Content-Length':len(data),
'Content-Type':'application/json;charset=utf-8',
'Pragma':'no-cache',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0'
}
req=urllib.request.Request('https://cp.kuaishou.com/rest/cp/works/v2/video/pc/upload/pre',data=data,method='POST')
req.headers=header3#模拟浏览器
#data=urllib.parse.urlencode(data).encode('utf-8')
html=opener.open(req,data).read()#html会返回验证码成功或不成功
#print(html.decode('utf8'))
提取字符串=html.decode('utf-8')
元组= re.search('token',提取字符串).span()
list_str = list(提取字符串)
for num in range(0,元组+8):
list_str.pop(0)
提取字符串 = ''.join(list_str)
元组= re.search('",',提取字符串).span()
list_str = list(提取字符串)
for num in range(元组,len(list_str)):
list_str.pop(元组)
提取字符串 = ''.join(list_str)
上传token=提取字符串
# print(上传token)
#2.https://upload.kuaishouzt.com/api/upload/resume #/api/上传/恢复
req=urllib.request.Request('https://upload.kuaishouzt.com/api/upload/resume?upload_token='+上传token)
req.headers=header#模拟浏览器
html=opener.open(req).read()#html会返回验证码成功或不成功
#print(html.decode('utf8'))
time.sleep(1)
#3.申请块上传文件
with open(列表,'rb') as f:
视频数据二进制=f.read()
文件大小=len(视频数据二进制)
文件大小2=文件大小
迭代次数 = 0
最后一次文件大小=0
while (迭代次数 < 100):
判断是否为负=文件大小2-4194304
if 判断是否为负 < 0:
#print(迭代次数)
最后一次文件大小=文件大小2
#print(最后一次文件大小)
break
迭代次数 = 迭代次数 + 1
文件大小2=判断是否为负
#print("迭代次数"+str(迭代次数))
if 迭代次数==0:
# print("进入迭代次数==0")
Content_Range='bytes 0-'+str(文件大小)+'/'+str(文件大小)
header_视频上传={
'Accept':'application/json, text/plain, */*',
'Accept-Encoding':'gzip, deflate, br',
'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',
'Connection':'keep-alive',
'Content-Length':len(视频数据二进制),
'Content-Range':Content_Range,
'Content-Type':'application/octet-stream',
'Host':'upload.kuaishouzt.com',
'Origin':'https://cp.kuaishou.com',
'Referer':'https://cp.kuaishou.com/article/publish/video?origin=www.kuaishou.com',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0'
}
req=urllib.request.Request('https://upload.kuaishouzt.com/api/upload/fragment?upload_token='+上传token+'&fragment_id=0',data=data,method='POST')
req.headers=header_视频上传#模拟浏览器
html=opener.open(req,视频数据二进制).read()#html会返回验证码成功或不成功
#print(html.decode('utf8'))
else:
for i in range(0,迭代次数):
# print("i"+str(i))
if i==迭代次数:
# print("进入最后上传块")
Content_Range='bytes '+str(迭代次数*4194304)+'-'+str(文件大小-1)+'/'+str(文件大小)
header_视频上传={
'Accept':'application/json, text/plain, */*',
'Accept-Encoding':'gzip, deflate, br',
'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',
'Connection':'keep-alive',
'Content-Length':最后一次文件大小,
'Content-Range':Content_Range,
'Content-Type':'application/octet-stream',
'Host':'upload.kuaishouzt.com',
'Origin':'https://cp.kuaishou.com',
'Referer':'https://cp.kuaishou.com/article/publish/video?origin=www.kuaishou.com',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0'
}
req=urllib.request.Request('https://upload.kuaishouzt.com/api/upload/fragment?upload_token='+上传token+'&fragment_id='+str(迭代次数),data=data,method='POST')
req.headers=header_视频上传#模拟浏览器
文件切割=视频数据二进制[迭代次数*4194304:文件大小]
# print("文件大小"+str(文件大小-迭代次数*4194304))
html=opener.open(req,文件切割).read()#html会返回验证码成功或不成功
else:
# print(str(i))
Content_Range='bytes '+str(i*4194304)+'-'+str((i+1)*4194304-1)+'/'+str(文件大小)
# Content_Range='bytes 0-4194303/11765090'
header_视频上传={
'Accept':'application/json, text/plain, */*',
'Accept-Encoding':'gzip, deflate, br',
'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',
'Connection':'keep-alive',
'Content-Length':4194304,
'Content-Range':Content_Range,
'Content-Type':'application/octet-stream',
'Host':'upload.kuaishouzt.com',
'Origin':'https://cp.kuaishou.com',
'Referer':'https://cp.kuaishou.com/article/publish/video?origin=www.kuaishou.com',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0'
}
req=urllib.request.Request('https://upload.kuaishouzt.com/api/upload/fragment?upload_token='+上传token+'&fragment_id='+str(i),data=data,method='POST')
req.headers=header_视频上传#模拟浏览器
文件切割=视频数据二进制
html=opener.open(req,文件切割).read()#html会返回验证码成功或不成功
#print("11111111111"+html.decode('utf8'))
# print(len(data))
header_视频上传={
'Accept':'application/json, text/plain, */*',
'Accept-Encoding':'gzip, deflate, br',
'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',
'Connection':'keep-alive',
'Content-Length':'0',
'Host':'upload.kuaishouzt.com',
'Origin':'https://cp.kuaishou.com',
'Referer':'https://cp.kuaishou.com/article/publish/video?origin=www.kuaishou.com',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0'
}
req=urllib.request.Request('https://upload.kuaishouzt.com/api/upload/complete?fragment_count=1&upload_token='+上传token,method='POST')
req.headers=header_视频上传#模拟浏览器
html=opener.open(req).read()#html会返回验证码成功或不成功
#print(html.decode('utf8'))
#3.文件上传完毕
data={
'fileLength':文件大小,#文件大小
'fileName':文件名,#文件名称
'fileType':'video/mp4',
'kuaishou.web.cp.api_ph':kuaishou_web_cp_api_ph,
'token':上传token
}
data=json.dumps(data).encode()
header3 ={
'Connection':'keep-alive',
'Content-Length':len(data),
'Content-Type':'application/json;charset=utf-8',
'Pragma':'no-cache',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0'
}
req=urllib.request.Request('https://cp.kuaishou.com/rest/cp/works/v2/video/pc/upload/finish',data=data,method='POST')
req.headers=header3#模拟浏览器
html=opener.open(req,data).read()#html会返回验证码成功或不成功
#print(html.decode('utf8'))
提取字符串=html.decode('utf-8')
元组= re.search('coverKey',提取字符串).span()
list_str = list(提取字符串)
for num in range(0,元组+8+3):
list_str.pop(0)
提取字符串 = ''.join(list_str)
元组= re.search('",',提取字符串).span()
list_str = list(提取字符串)
for num in range(元组,len(list_str)):
list_str.pop(元组)
提取字符串 = ''.join(list_str)
coverKey=提取字符串
#print(coverKey)
提取字符串=html.decode('utf-8')
元组= re.search('fileId',提取字符串).span()
list_str = list(提取字符串)
for num in range(0,元组+6+2):
list_str.pop(0)
提取字符串 = ''.join(list_str)
元组= re.search(',"',提取字符串).span()
list_str = list(提取字符串)
for num in range(元组,len(list_str)):
list_str.pop(元组)
提取字符串 = ''.join(list_str)
fileId=提取字符串
# print(fileId)
#发布视频
data={
'caption':"",
'collectionId':"",
'coverCenterX':"",
'coverCenterY':"",
'coverCropped':'false',
'coverKey':coverKey,
'coverTimeStamp':-1,
'coverTitle':"",
'coverTitleStyle':"",
'coverType':1,
'domain':"",
'fileId':fileId,
'kuaishou.web.cp.api_ph':kuaishou_web_cp_api_ph,
'latitude':"",
'longitude':"",
'movieId':"",
'notifyResult':0,
'photoStatus':1,
'photoType':0,
'pkCoverKey':"",
'publishTime':0,
'secondDomain':""
}
data=json.dumps(data).encode()
header_submit ={
'Connection':'keep-alive',
'Content-Length':len(data),
'Content-Type':'application/json;charset=utf-8',
'Pragma':'no-cache',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0'
}
req=urllib.request.Request('https://cp.kuaishou.com/rest/cp/works/v2/video/pc/submit',data=data,method='POST')
req.headers=header_submit#模拟浏览器
html=opener.open(req,data).read()#html会返回验证码成功或不成功
print(html.decode('utf8'))
os.remove(列表)
列表.remove(列表)
login()
看完了,但是我还是不敢用,我感觉快手封号挺严重的,最初批量模拟器搞过快手永久封了一堆,后来手机群控快手,还是有个别的封号(永久封闭),当然没有发布违法违规视频,仅仅是批量发布作品,批量登陆等.... 衣惠纺 发表于 2021-2-21 20:34
看完了,但是我还是不敢用,我感觉快手封号挺严重的,最初批量模拟器搞过快手永久封了一堆,后来手机群控快 ...
我用了,还可以,只不过如果发别人发过的视频,就会被限流 {:1_921:}能弄个定时上传那更利害了 众益科技 发表于 2021-2-21 20:32
能弄个定时上传那更利害了
我这个源码里有定时上传,每分钟上传一个,你也可以改成两分钟一个 嗯嗯 现在我都不咋搞快手了,动不动就封我号{:1_889:} 衣惠纺 发表于 2021-2-21 20:52
嗯嗯 现在我都不咋搞快手了,动不动就封我号
请问抖音怎么样,限流几率高吗 相比快手,抖音还好搞,没碰到永久封号问题,快手永久封号是真恶心我。(没发违法违规的视频,仅仅是批量问题永久封号) 上传一个视频热门不了,还批量。{:301_971:} A风继续吹 发表于 2021-2-21 21:00
上传一个视频热门不了,还批量。
要想搞卧龙寺那种脚本,批量上传视频还是很重要的