代码拉取完成,页面将自动刷新
# -*- coding: utf-8 -*-
import base64
from threading import Thread
import time
import requests
import logging
from io import BytesIO
import http.cookiejar as cookielib
from PIL import Image
import os, sys
requests.packages.urllib3.disable_warnings()
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0'}
logger = logging.getLogger(__name__)
def initloger():
if not os.path.exists('./logs'):
os.mkdir('./logs')
logger.setLevel(logging.DEBUG)
fh = logging.FileHandler('./logs/{}.log'.format(time.strftime('%Y%m%d', time.localtime(time.time()))), encoding='utf-8',mode='a')
formatter = logging.Formatter("%(asctime)s - %(message)s", datefmt='%Y-%m-%d %H:%M:%S')
fh.setFormatter(formatter)
logger.addHandler(fh)
sh = logging.StreamHandler()
sh.setFormatter(formatter)
logger.addHandler(sh)
initloger()
class showpng(Thread):
def __init__(self, data):
Thread.__init__(self)
self.data = data
def run(self):
img = Image.open(BytesIO(self.data))
img.show()
def islogin(session):
try:
session.cookies.load(ignore_discard=True)
except Exception:
pass
cookies = getcookies(session)
api_ph = cookies['kuaishou.web.cp.api_ph']
res = session.post("https://cp.kuaishou.com/rest/pc/authority/account/current", json={"kuaishou.web.cp.api_ph": api_ph}, verify=False, headers=headers).json()
if res['result'] == 1:
# logger.info('Cookies值有效,无需扫码登录!')
return session, True
else:
logger.info('Cookies值失效,请重新扫码登录!')
return session, False
def login(userid, logtype='qrcode'):
cookiefile = './cache/%s.txt' % userid
if not os.path.exists(cookiefile):
with open(cookiefile, 'w') as f:
f.write('')
session = requests.session()
session.cookies = cookielib.LWPCookieJar(filename=cookiefile)
session, status = islogin(session)
if not status:
urldata = session.post('https://id.kuaishou.com/rest/c/infra/ks/qr/start', data={"sid": "kuaishou.web.cp.api"}, headers=headers).json()
testpng = base64.b64decode(urldata['imageData'])
token = urldata['qrLoginToken']
Signat = urldata['qrLoginSignature']
t = showpng(testpng)
t.start()
tokenurl = 'https://id.kuaishou.com/rest/c/infra/ks/qr/scanResult'
while True:
tokendata = session.post(tokenurl, data={"qrLoginToken": token, "qrLoginSignature": Signat}, headers=headers).json()
if tokendata['result'] == 707:
logger.info('登录二维码已过期,请重新运行')
if tokendata['result'] == 1:
data = session.post('https://id.kuaishou.com/rest/c/infra/ks/qr/acceptResult', data={"qrLoginToken": token, "qrLoginSignature": Signat, "sid": "kuaishou.web.cp.api"}, headers=headers)
data1 = session.post('https://id.kuaishou.com/pass/kuaishou/login/qr/callback', data={"qrToken": data.json()['qrToken'], "sid": "kuaishou.web.cp.api"}, headers=headers)
session.post('https://www.kuaishou.com/account/login/api/verifyToken', json={"authToken": data1.json()['kuaishou.web.cp.api.at'], "sid": "kuaishou.web.cp.api"}, headers=headers)
logger.info('已确认,登录成功')
break
time.sleep(3)
session.cookies.save()
return session
def smslogin(phone):
data = {
'sid': 'kuaishou.web.cp.api',
'type': '53',
'countryCode': '+86',
'phone': phone,
'ztIdentityVerificationType': '',
'ztIdentityVerificationCheckToken': ''
}
res = session.post('https://id.kuaishou.com/pass/kuaishou/sms/requestMobileCode', data=data, headers=headers).json()
if res['result'] == 1:
data1 = {
'sid': 'kuaishou.web.cp.api',
'countryCode': '+86',
'createId': 'true',
'phone': phone,
'smsCode': code
}
req = session.post('https://id.kuaishou.com/pass/kuaishou/login/mobileCode', data=data1, headers=headers).json()
if req['result'] == 100110007:
logger.info(req['error_msg'])
if req['result'] == 100110031:
multiUserToken = res['multiUserToken']
targetUserId = res['userInfos'][1]['userId']
data2 = {
'sid': 'kuaishou.web.cp.api',
'countryCode': '+86',
'account': '',
'targetUserId': targetUserId,
'multiUserToken': multiUserToken,
'phone': phone,
'setCookie': 'true'
}
session.post('https://id.kuaishou.com/pass/kuaishou/login/multiUserToken', data=data2, headers=headers)
if req['result'] == 1:
session.post('https://www.kuaishou.com/account/login/api/verifyToken', json={"authToken": data1.json()['kuaishou.web.cp.api.at'], "sid": "kuaishou.web.cp.api"}, headers=headers)
def getaccount(session):
cookies = getcookies(session)
api_ph = cookies['kuaishou.web.cp.api_ph']
req = session.post('https://cp.kuaishou.com/rest/pc/authority/account/current', json={"kuaishou.web.cp.api_ph": api_ph}, headers=headers)
res = req.json()
if res['result'] == 1:
userId = res['data']['userId']
userName = res['data']['userName']
userAvatar = res['data']['userAvatar']
return userId, userName, userAvatar
return False
def getcookies(session):
cookies = {}
for ck in session.cookies:
cookies[ck.name] = ck.value
return cookies
def uploadtoken(session):
# 1获取上传token
cookies = getcookies(session)
api_ph = cookies['kuaishou.web.cp.api_ph']
req = session.post('https://cp.kuaishou.com/rest/cp/works/v2/video/pc/upload/pre', json={"kuaishou.web.cp.api_ph": api_ph, "uploadType": "1"}, headers=headers)
res = req.json()
if res['result'] == 1:
token = res['data']['token']
else:
logger.info(res['message'])
# 2申请上传
session.get('https://upload.kuaishouzt.com/api/upload/resume?upload_token=%s' % token)
return token, api_ph
def workslist(session):
def convertTime(fmtime):
return time.mktime(time.strptime(fmtime, "%Y-%m-%d %H:%M:%S"))
cookies = getcookies(session)
userId = cookies['userId']
api_ph = cookies['kuaishou.web.cp.api_ph']
endTime = int(convertTime(time.strftime("%Y-%m-%d 23:59:59", time.localtime(time.time()))) * 1000)
startTime = endTime - 7*86400*1000 + 1000
data = {
"userId":userId,
"status":1,
"endTime":endTime,
"startTime":startTime,
"dateType":3,
"count":50,
"page":1,
"kuaishou.web.cp.api_ph":api_ph
}
res = session.post('https://cp.kuaishou.com/rest/pc/user/works/list', data=data, headers=headers).json()
if res['result'] == 1:
totalCount = res['data']['totalCount']
pageCount = int(int(totalCount + 50 - 1) / 50)
for work in res['data']['works']:
workId, title, cover, uploadTime, playCount, likeCount, commentCount = '','','','','','',''
def upvideo(session, fname):
uptoken, api_ph = uploadtoken(session)
with open(fname, 'rb') as f:
f.seek(0, 2)
flen = f.tell()
f.seek(0, 0)
i = 0
while True:
chunk = f.read(4194304)
if not chunk:
break
# 按4M大小分块上传视频
upload(session, uptoken, chunk, flen, i)
i += 1
try:
# 校验上传完成
coverKey, fileId = upload_check(session, uptoken, api_ph, fname, flen, i)
# 发布
result = submit(session, api_ph, coverKey, fileId, '同城交友', '', '')
except Exception as e:
logger.info('Error#' + str(e))
result = False
return result
def upload(session, uptoken, chunk, flen, i):
Content_Range = 'bytes %s-%s/%s' % (str(i*4194304), str((i+1)*4194304-1), str(flen))
headersx = {
'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':str(len(chunk)),
'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'
}
session.post('https://upload.kuaishouzt.com/api/upload/fragment?upload_token=%s&fragment_id=%s' % (uptoken, i), data=chunk, headers=headersx, stream=True)
def upload_check(session, uptoken, api_ph, fname, flen, fragment):
req = session.post('https://upload.kuaishouzt.com/api/upload/complete?fragment_count=%s&upload_token=%s' % (fragment, uptoken), json={}, headers=headers, verify=False)
#print(req.text)
res = req.json()
data = {
'fileLength': flen,
'fileName': os.path.basename(fname),
'fileType': 'video/mp4',
'kuaishou.web.cp.api_ph': api_ph,
'token': uptoken
}
req = session.post('https://cp.kuaishou.com/rest/cp/works/v2/video/pc/upload/finish', json=data, headers=headers)
#print(req.text)
res = req.json()
if res['result'] == 1:
return res['data']['coverKey'], res['data']['fileId']
else:
logger.info(res['message'])
return '', ''
def submit(session, api_ph, coverKey, fileId, caption = '', longitude = '', latitude = ''):
data={
'caption': caption,
'collectionId':"",
'coverCenterX':"",
'coverCenterY':"",
'coverCropped':'false',
'coverKey':coverKey,
'coverTimeStamp':-1,
'coverTitle':"",
'coverTitleStyle':"",
'coverType':1,
'domain':"",
'fileId':fileId,
'kuaishou.web.cp.api_ph':api_ph,
'latitude': latitude,
'longitude': longitude,
'movieId':"",
'notifyResult':0,
'photoStatus':1,
'photoType':0,
'pkCoverKey':"",
'publishTime':0,
'secondDomain':""
}
session.post('https://cp.kuaishou.com/rest/cp/works/v2/video/pc/submit', json=data, headers=headers)
return True
def worker(curpath, unlink = False):
userid = curpath.split('\\')[-1]
session = login(userid)
filenum = 0
fileset = set()
for root, dirs, files in os.walk(curpath):
for f in files:
if f.endswith('.mp4'):
fileset.add(os.path.join(root, f))
filenum += 1
fileset = list(fileset)
logger.info('%s共%s个视频' % (curpath, str(filenum)))
for i in range(0, filenum):
time.sleep(3)
fname = fileset[i]
logger.info('正在上传%s_%s_%s' % (curpath, str(i+1), fname))
#发布内容
result = upvideo(session, fname)
if result is True and unlink is True:
os.remove(fname)
def traceexcept(type, value, trace):
log = 'Trace#' + str(type) + '::' + str(value)
while trace:
log += os.linesep + ' File ' + str(trace.tb_frame.f_code.co_filename) + ', Line ' + str(trace.tb_lineno)
trace = trace.tb_next
logger.error(log)
if __name__ == '__main__':
sys.excepthook = traceexcept
# 视频文件夹
curpath = sys.argv[1] if len(sys.argv)>1 else './'
# 上传完成后是否删除
unlink = True if len(sys.argv)>2 else False
worker(curpath, unlink)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。