huguo002 发表于 2023-3-24 18:17

Python短视频下载工具,快手短视频批量下载工具及源码

本帖最后由 huguo002 于 2023-3-24 18:21 编辑

做自媒体短视频,一些平台的视频无疑是需要下载的,那么今天这篇就带来快手短视频下载工具,总结了一下短视频下载工具,供大家参考和学习,当然仅仅是本渣渣的一些使用分享而已!

方式一:浏览器插件下载这一方法无疑是比较简单的,而且有很多视频解析插件可以使用,不过部分较长视频无法解析下载,仅供参考!
本渣渣这里用的是:Flash Video Downloader



例如:https://www.kuaishou.com/f/X9yqpxiPsYhy1Kn


方式二:在线网页解析工具这一方法也是比较简单的,直接用网上大佬分享的在线网页解析工具即可下载短视频!
例如:1.多平台短视频下载(快手接口失效)https://watermark.iculture.cc/2.抖音短视频下载https://ouotool.com/dy

Python源码参考
以第一个平台为例,简单的用Python写一个模拟访问获取视频的源码:

# -*-coding:utf-8-*-
import requests
import time
from contextlib import closing

def get_video_url(url):
    """
    在线解析短视频地址
    :param url: 短视频分享地址
    :return:
    """
    headers={
      "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
    }
    jkurl=f"https://api.iculture.cc/api/video/?url={url}"
    response=requests.get(url=jkurl,headers=headers,timeout=6)
    print(response.status_code)
    time.sleep(2)
    # print(response.json())
    response_json=response.json()
    print(response_json['msg'])
    video_title=response_json['title']
    print(video_title)
    video_url=response_json['url']
    print(video_url)
    video=video_title,video_url
    return video

def get_video(video_title,video_url):
    """
    下载视频
    :param video_title: 视频标题
    :param video_url: 视频地址
    :return:
    """
    url = video_url
    headers = {
      'user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.42'
    }
    response = requests.get(url=url, headers=headers, timeout=10, stream=True)
    with open(f'{video_title}.mp4','wb') as f:
      f.write(response.content)
    print(f'{video_title}下载完成')


def down_video(video_title,video_url):
    """
    带进度条显示下载视频
    :param video_title: 视频标题
    :param video_url: 视频地址
    :return:
    """
    url =video_url
    headers = {
      'user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.42'
    }
    with closing(requests.get(url=url,headers=headers, stream=True)) as response:
      chunk_size = 1024# 单次请求最大值
      # response.headers['content-length']得到的数据类型是str而不是int
      content_size = int(response.headers['content-length'])# 文件总大小
      data_count = 0# 当前已传输的大小
      with open(f'{video_title}.mp4', "wb") as file:
            for data in response.iter_content(chunk_size=chunk_size):
                file.write(data)
                done_block = int((data_count / content_size) * 50)
                # 已经下载的文件大小
                data_count = data_count + len(data)
                # 实时进度条进度
                now_jd = (data_count / content_size) * 100
                # %% 表示%
                print("\r [%s%s] %d%% " % (done_block * '█', ' ' * (50 - 1 - done_block), now_jd), end=" ")
    print(f'{video_title}.mp4 下载完成!')

if __name__=="__main__":
    url="http://v.douyin.com/uycNy6/"
    #url="https://www.kuaishou.com/f/X-1JB88iJi3UY13A"
    video=get_video_url(url)
    video_title=video
    video_url=video
    # get_video(video_title, video_url)
    down_video(video_title, video_url)

方式三:Python批量下载工具
例如:https://www.kuaishou.com/profile/3xk2asbe3pqa2ds

浏览器关键抓包信息内容:






本渣渣参考写的代码:

-*-coding:utf-8-*-
import requests
import time
from contextlib import closing
import re

def get_vedio_list(id,did):
    """
    解析用户主页视频
    :param id: 用户id
    :param did: Cookies
    :return:
    """
    url="https://www.kuaishou.com/graphql"
    headers={
      'content-type': 'application/json',
      'Host': 'www.kuaishou.com',
      'Origin': 'https://www.kuaishou.com',
      'Referer': f'https://www.kuaishou.com/profile/{id}',
      "Cookie": f"kpf=PC_WEB; clientid=3; did={did}",

      "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36",
    }
    data={
      "operationName": "visionProfilePhotoList",
      "query": "fragment photoContent on PhotoEntity {\nid\nduration\ncaption\noriginCaption\nlikeCount\nviewCount\nrealLikeCount\ncoverUrl\nphotoUrl\nphotoH265Url\nmanifest\nmanifestH265\nvideoResource\ncoverUrls {\n    url\n    __typename\n}\ntimestamp\nexpTag\nanimatedCoverUrl\ndistance\nvideoRatio\nliked\nstereoType\nprofileUserTopPhoto\nmusicBlocked\n__typename\n}\n\nfragment feedContent on Feed {\ntype\nauthor {\n    id\n    name\n    headerUrl\n    following\n    headerUrls {\n      url\n      __typename\n    }\n    __typename\n}\nphoto {\n    ...photoContent\n    __typename\n}\ncanAddComment\nllsid\nstatus\ncurrentPcursor\ntags {\n    type\n    name\n    __typename\n}\n__typename\n}\n\nquery visionProfilePhotoList($pcursor: String, $userId: String, $page: String, $webPageArea: String) {\nvisionProfilePhotoList(pcursor: $pcursor, userId: $userId, page: $page, webPageArea: $webPageArea) {\n    result\n    llsid\n    webPageArea\n    feeds {\n      ...feedContent\n      __typename\n    }\n    hostName\n    pcursor\n    __typename\n}\n}\n",
      "variables": {"userId": f'{id}', "pcursor": "", "page": "profile"},
    }
    response=requests.post(url=url,json=data,headers=headers,timeout=6)
    print(response.json())
    response_json=response.json()
    data_json=response_json['data']['visionProfilePhotoList']
    print(data_json['pcursor'])# 下一页地址参数
    video_lists=data_json['feeds']
    for video_list in video_lists:
      # print(video_list)
      video_title=video_list['photo']['originCaption']
      video_title=filter_title(video_title) #标题特殊字符过滤
      print(video_title)
      video_url=video_list['photo']['photoUrl']
      print(video_url)
      down_video(video_title, video_url) #下载视频
      time.sleep(3)


def filter_title(title):
    """
    标题特殊字符过滤处理
    :param title: 视频标题
    :return:
    """
    title = title.strip()
    rstr = r"[\/\\\:\*\?\"\<\>\|\.\,|\r\n]+"
    new_title = re.sub(rstr,'_',title)
    return new_title

def get_video(video_title,video_url):
    """
    下载视频
    :param video_title: 视频标题
    :param video_url: 视频地址
    :return:
    """
    url = video_url
    headers = {
      'user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.42'
    }
    response = requests.get(url=url, headers=headers, timeout=10, stream=True)
    with open(f'{video_title}.mp4','wb') as f:
      f.write(response.content)
    print(f'{video_title}下载完成')


def down_video(video_title,video_url):
    """
    带进度条显示下载视频
    :param video_title: 视频标题
    :param video_url: 视频地址
    :return:
    """
    url =video_url
    headers = {
      'user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.42'
    }
    with closing(requests.get(url=url,headers=headers, stream=True)) as response:
      chunk_size = 1024# 单次请求最大值
      # response.headers['content-length']得到的数据类型是str而不是int
      content_size = int(response.headers['content-length'])# 文件总大小
      data_count = 0# 当前已传输的大小
      with open(f'{video_title}.mp4', "wb") as file:
            for data in response.iter_content(chunk_size=chunk_size):
                file.write(data)
                done_block = int((data_count / content_size) * 50)
                # 已经下载的文件大小
                data_count = data_count + len(data)
                # 实时进度条进度
                now_jd = (data_count / content_size) * 100
                # %% 表示%
                print("\r [%s%s] %d%% " % (done_block * '█', ' ' * (50 - 1 - done_block), now_jd), end=" ")
    print(f'{video_title}.mp4 下载完成!')



if __name__=='__main__':
    id="3xk2asbe3pqa2ds"
    did=did
    get_vedio_list(id,did)


几个关键点:
1.requests.post json 请求数据方式

2.头部 headers 和 请求的json 请求数据 须正确
3.Cookie 须正常账号登陆获取
4.pcursor 下一页地址参数获取


实现效果:


https://mmbiz.qpic.cn/mmbiz_gif/EUOOgrohSX964yceyu2lCAQyPfj9zAHEwO6mcvKEdxZLicsS6UbXavZB4nlMniaRaHDYbL4MNZnpM8ZsqsYbJXWQ/640?wx_fmt=gif

exe工具
异步大佬的https://www.52pojie.cn/thread-1668148-1-1.html

我就不献丑了.......

参考来源:
1.快手短视频下载V1.91
https://www.52pojie.cn/thread-1631965-1-1.html

2.快手视频下载,指定作者批量下载无水印
https://www.52pojie.cn/thread-1668148-1-1.html

3.python中Requests发送json格式的post请求方法
https://www.jb51.net/article/262153.htm

仅供参考,学习,有用可以点个赞,支持一下!

佚名RJ 发表于 2023-3-24 19:00

还有一种方法,就是使用聚合解析的工具,有需要的可以试试看!

【更新V2.0】聚合短视频解析V2.0版本-支持国内外众多短视频平台
https://www.52pojie.cn/thread-1741650-1-1.html (出处: 吾爱破解论坛)

sndncel 发表于 2023-3-31 22:47

其实楼主的这个代码已经很简洁了。我只是稍微修改了一点点。
1.使用response.raise_for_status()可以让程序在请求出错时立即抛出异常,避免在下载大文件时出现错误但长时间无响应的情况。
2.使用tqdm库可以让下载进度更加直观。
3.将获取视频信息和下载视频分开为两个函数,使代码结构更加清晰。
# -*- coding: utf-8 -*-

import requests
import time
from tqdm import tqdm


def get_video_info(url):
    """
    获取短视频信息,包括标题和视频地址
    :param url: 短视频分享地址
    :return: 字典,包括标题和视频地址
    """
    headers = {
      "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
    }
    jkurl = f"https://api.iculture.cc/api/video/?url={url}"
    response = requests.get(url=jkurl, headers=headers, timeout=6)
    response.raise_for_status()
    time.sleep(2)
    response_json = response.json()
    video_title = response_json['title']
    video_url = response_json['url']
    video_info = {'title': video_title, 'url': video_url}
    return video_info


def download_video(video_info, use_tqdm=True):
    """
    下载视频,并显示进度条
    :param video_info: 包括视频标题和地址的字典
    :param use_tqdm: 是否使用进度条
    :return: None
    """
    url = video_info['url']
    headers = {
      'user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.42'
    }
    response = requests.get(url=url, headers=headers, timeout=10, stream=True)
    response.raise_for_status()
    total_size = int(response.headers.get('content-length', 0))# 文件总大小
    block_size = 1024# 单次请求最大值
    with open(f"{video_info['title']}.mp4", "wb") as file:
      if use_tqdm:
            with tqdm(total=total_size, unit='B', unit_scale=True, desc=video_info['title']) as pbar:
                for data in response.iter_content(chunk_size=block_size):
                  file.write(data)
                  pbar.update(len(data))
      else:
            for data in response.iter_content(chunk_size=block_size):
                file.write(data)
    print(f"{video_info['title']}.mp4 下载完成!")


if __name__ == "__main__":
    url = "http://v.douyin.com/uycNy6/"
    video_info = get_video_info(url)
    download_video(video_info, use_tqdm=True)

wakichie 发表于 2023-3-24 18:28

大佬厉害了,学习了

hyz20230313 发表于 2023-3-24 18:29

mark,学习了。

eerrtr3 发表于 2023-3-24 18:55

有没有快手或者抖音的批量文案下载工具啊

tom350 发表于 2023-3-24 18:57

学到了,感谢

CanLG 发表于 2023-3-24 19:19

学习一下,感谢大佬分享

weiyanli 发表于 2023-3-24 19:24

已学习,感谢大佬

jeromelin2023 发表于 2023-3-24 19:29

谢谢大佬

Rueng6009 发表于 2023-3-24 20:03

参考学习一下!
页: [1] 2 3 4
查看完整版本: Python短视频下载工具,快手短视频批量下载工具及源码