命夜嚣色 发表于 2021-2-21 20:09

快手批量上传视频

本帖最后由 命夜嚣色 于 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

看完了,但是我还是不敢用,我感觉快手封号挺严重的,最初批量模拟器搞过快手永久封了一堆,后来手机群控快手,还是有个别的封号(永久封闭),当然没有发布违法违规视频,仅仅是批量发布作品,批量登陆等....

命夜嚣色 发表于 2021-2-21 20:39

衣惠纺 发表于 2021-2-21 20:34
看完了,但是我还是不敢用,我感觉快手封号挺严重的,最初批量模拟器搞过快手永久封了一堆,后来手机群控快 ...

我用了,还可以,只不过如果发别人发过的视频,就会被限流

众益科技 发表于 2021-2-21 20:32

{:1_921:}能弄个定时上传那更利害了

命夜嚣色 发表于 2021-2-21 20:38

众益科技 发表于 2021-2-21 20:32
能弄个定时上传那更利害了

我这个源码里有定时上传,每分钟上传一个,你也可以改成两分钟一个

衣惠纺 发表于 2021-2-21 20:52

嗯嗯 现在我都不咋搞快手了,动不动就封我号{:1_889:}

命夜嚣色 发表于 2021-2-21 20:53

衣惠纺 发表于 2021-2-21 20:52
嗯嗯 现在我都不咋搞快手了,动不动就封我号

请问抖音怎么样,限流几率高吗

衣惠纺 发表于 2021-2-21 20:56

相比快手,抖音还好搞,没碰到永久封号问题,快手永久封号是真恶心我。(没发违法违规的视频,仅仅是批量问题永久封号)

A风继续吹 发表于 2021-2-21 21:00

上传一个视频热门不了,还批量。{:301_971:}

命夜嚣色 发表于 2021-2-21 21:30

A风继续吹 发表于 2021-2-21 21:00
上传一个视频热门不了,还批量。
要想搞卧龙寺那种脚本,批量上传视频还是很重要的
页: [1] 2 3 4
查看完整版本: 快手批量上传视频