吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 8996|回复: 31
上一主题 下一主题
收起左侧

[Python 转载] 快手批量上传视频

[复制链接]
跳转到指定楼层
楼主
命夜嚣色 发表于 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就是块文件的第一个文件,这里就不多讲了





[md][/md]
文件上传完毕,获取coverKey和fileId:






我估计抖音的也是用的块上传,也是二进制传输文件


整体过程就像是玩解密游戏一样,还是挺有趣的
发布视频参数就都获取完了,也没有什么好讲的了,下面直接发源码



[Python] 纯文本查看 复制代码
#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,元组[0]+25):
        list_str.pop(0)
    提取字符串 = ''.join(list_str)




    元组= re.search('",',提取字符串).span()
    
    list_str = list(提取字符串)
    for num in range(元组[0],len(list_str)):
        list_str.pop(元组[0])

    提取字符串 = ''.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,元组[0]+25):
        list_str.pop(0)
    提取字符串 = ''.join(list_str)
    



    元组= re.search('",',提取字符串).span()
    list_str = list(提取字符串)
    for num in range(元组[0],len(list_str)):
        list_str.pop(元组[0])
    提取字符串 = ''.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*定时)#秒

       


        文件名=列表[0]
        真与假=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,元组[0]+8):
            list_str.pop(0)
        提取字符串 = ''.join(list_str)


        元组= re.search('",',提取字符串).span()
        list_str = list(提取字符串)
        for num in range(元组[0],len(list_str)):
            list_str.pop(元组[0])
        提取字符串 = ''.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(列表[0],'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_视频上传#模拟浏览器

                    文件切割=视频数据二进制[i*4194304:(i+1)*4194304]

                    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,元组[0]+8+3):
            list_str.pop(0)
        提取字符串 = ''.join(list_str)


        元组= re.search('",',提取字符串).span()
        list_str = list(提取字符串)
        for num in range(元组[0],len(list_str)):
            list_str.pop(元组[0])
        提取字符串 = ''.join(list_str)


        coverKey=提取字符串

        #print(coverKey)



        提取字符串=html.decode('utf-8')
        元组= re.search('fileId',提取字符串).span()
        list_str = list(提取字符串)
        for num in range(0,元组[0]+6+2):
            list_str.pop(0)
        提取字符串 = ''.join(list_str)


        元组= re.search(',"',提取字符串).span()
        list_str = list(提取字符串)
        for num in range(元组[0],len(list_str)):
            list_str.pop(元组[0])
        提取字符串 = ''.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(列表[0]) 

        列表.remove(列表[0])




login()





本帖被以下淘专辑推荐:

  • · 好帖|主题: 540, 订阅: 84

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
衣惠纺 发表于 2021-2-21 20:34
看完了,但是我还是不敢用,我感觉快手封号挺严重的,最初批量模拟器搞过快手永久封了一堆,后来手机群控快手,还是有个别的封号(永久封闭),当然没有发布违法违规视频,仅仅是批量发布作品,批量登陆等....
推荐
 楼主| 命夜嚣色 发表于 2021-2-21 20:39 |楼主
衣惠纺 发表于 2021-2-21 20:34
看完了,但是我还是不敢用,我感觉快手封号挺严重的,最初批量模拟器搞过快手永久封了一堆,后来手机群控快 ...

我用了,还可以,只不过如果发别人发过的视频,就会被限流
4#
众益科技 发表于 2021-2-21 20:32
5#
 楼主| 命夜嚣色 发表于 2021-2-21 20:38 |楼主
众益科技 发表于 2021-2-21 20:32
能弄个定时上传那更利害了

我这个源码里有定时上传,每分钟上传一个,你也可以改成两分钟一个
6#
衣惠纺 发表于 2021-2-21 20:52
嗯嗯 现在我都不咋搞快手了,动不动就封我号
7#
 楼主| 命夜嚣色 发表于 2021-2-21 20:53 |楼主
衣惠纺 发表于 2021-2-21 20:52
嗯嗯 现在我都不咋搞快手了,动不动就封我号

请问抖音怎么样,限流几率高吗
8#
衣惠纺 发表于 2021-2-21 20:56
相比快手,抖音还好搞,没碰到永久封号问题,快手永久封号是真恶心我。(没发违法违规的视频,仅仅是批量问题永久封号)

免费评分

参与人数 1热心值 +1 收起 理由
命夜嚣色 + 1 谢谢@Thanks!

查看全部评分

9#
A风继续吹 发表于 2021-2-21 21:00
上传一个视频热门不了,还批量。
10#
 楼主| 命夜嚣色 发表于 2021-2-21 21:30 |楼主
A风继续吹 发表于 2021-2-21 21:00
上传一个视频热门不了,还批量。

要想搞卧龙寺那种脚本,批量上传视频还是很重要的
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-29 09:22

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表