欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

python 爬虫 爬取快手短视频无水印视频解析最新版

程序员文章站 2022-03-15 15:01:50
要素过多建议收藏首先打开复制的一个链接发现复制直接打开到浏览器不行,不是我们想要的内容,然后我们就复制这个里面的url部分打开浏览器就可以了但是打开之后发现一些端倪,视频可以正常看,但是url变了不是原来的url了,这里先暂且不管,后面再解释首先先找到视频的url ,按照惯例,通常视频的url链接不会出现在网页源码中,一种可能是通过分段的视频文件动态加载再进行合成,这种方式常被用于长视频之类的,比如哔哩哔哩,腾讯视频等,快手这种短的几分钟的视频通常会把视频的url储存在json数据里面,...

要素过多建议收藏
首先打开复制的一个链接
python 爬虫 爬取快手短视频无水印视频解析最新版
发现复制直接打开到浏览器不行,不是我们想要的内容,
python 爬虫 爬取快手短视频无水印视频解析最新版
然后我们就复制这个里面的url部分打开浏览器就可以了

python 爬虫 爬取快手短视频无水印视频解析最新版
但是打开之后发现一些端倪,视频可以正常看,但是url变了不是原来的url了,

python 爬虫 爬取快手短视频无水印视频解析最新版
这里先暂且不管,后面再解释

首先先找到视频的url ,按照惯例,通常视频的url链接不会出现在网页源码中,一种可能是通过分段的视频文件动态加载再进行合成,这种方式常被用于长视频之类的,比如哔哩哔哩,腾讯视频等,快手这种短的几分钟的视频通常会把视频的url储存在json数据里面,当然哔哩哔哩也会有采用形式的视频,在之前项目中有遇到过,

进入正题:

首先打开抓包工具,刷新下页面

python 爬虫 爬取快手短视频无水印视频解析最新版
然后我们Ctrl + a 全选这段json

百度搜索json在线解析工具,复制这段json进行解析,方便查看

python 爬虫 爬取快手短视频无水印视频解析最新版
并且视频不带快手的水印

python 爬虫 爬取快手短视频无水印视频解析最新版
然后咱们先测试一下,看看使用代码请求这段url能不能回去视频内容

import requests
import os

if __name__ == '__main__':
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36'
    }
    url = 'https://txmov2.a.yximgs.com/upic/2020/12/05/17/BMjAyMDEyMDUxNzAxMTFfMTQ1NDE4NzgxM180MDI1NjI3OTAyM18wXzM=_b_B74de4e1df453284acb277ef56374d4a3.mp4?tag=1-1607416509-xpcwebfeatured-0-tzrke3v4lu-b5aedf898d64de53&clientCacheKey=3xq8eqfzukc9ifa_b.mp4&tt=b&di=7b0d5dda&bp=10004'

    r = requests.get(url=url,headers=headers).content

    title_path = './快手'
    if not os.path.exists(title_path):
        os.mkdir(title_path)

    mp4name = 'test.mp4'
    mp4path = title_path + '/' + mp4name

    with open(mp4path,'wb') as fp:
        fp.write(r)

运行之后,打开文件夹发现可以播放,且无水印跟刚才一样

python 爬虫 爬取快手短视频无水印视频解析最新版
那么我们就知道啦,只要得到这个json数据,在提取出里面的url就可以下载无水印的视频了,

那么问题来了们如何获取这个json呢?往下看

打开抓包工机看这个headers观察看看

发现是个post请求,并且需要传递payload参数

python 爬虫 爬取快手短视频无水印视频解析最新版
那么我们是以下看看能不能通过post请求来获取我们需要的json数据

import requests
import os
import json

if __name__ == '__main__':
    # 注意请求头加上content-type
    headers = {
        'content-type': 'application/json',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36'
    }
    
    url = 'https://video.kuaishou.com/graphql'

    data = {"operationName":"visionVideoDetail","variables":{"photoId":"3xq8eqfzukc9ifa","page":"selected"},"query":"query visionVideoDetail($photoId: String, $type: String, $page: String) {\n  visionVideoDetail(photoId: $photoId, type: $type, page: $page) {\n    status\n    type\n    author {\n      id\n      name\n      following\n      headerUrl\n      __typename\n    }\n    photo {\n      id\n      duration\n      caption\n      likeCount\n      realLikeCount\n      coverUrl\n      photoUrl\n      liked\n      timestamp\n      expTag\n      llsid\n      __typename\n    }\n    tags {\n      type\n      name\n      __typename\n    }\n    commentLimit {\n      canAddComment\n      __typename\n    }\n    llsid\n    __typename\n  }\n}\n"}
    data1 = json.dumps(data)    # 这里是字典转成json字符串 因为payload参数接受的json格式的 不是字典格式的

    resp = requests.post(url=url,headers=headers,data=data1).json()
    print(resp)

运行之后发现可以获得我们需要的json数据

python 爬虫 爬取快手短视频无水印视频解析最新版
然后经过提取获得完整的url

python 爬虫 爬取快手短视频无水印视频解析最新版
然后我们发现,现在的问题是我们需要将每个data里面的photoid 换成我们想要提取的视频的id ,其他不变

就是这个东西

python 爬虫 爬取快手短视频无水印视频解析最新版
然后我们发现这个东西就是开始我们打开的复制过来的链接

python 爬虫 爬取快手短视频无水印视频解析最新版
那么我们回到了之前的问题怎么转成这个链接呢

我们再次复制打开啊发现这里有个小细节

python 爬虫 爬取快手短视频无水印视频解析最新版
请求头里的host是这样的,那么就意味着之前的短链接是通过post请求返回了长链接

那么我们试一下看看猜想是否成立

import requests
import re

if __name__ == '__main__':

    headers = {
        'Host': 'v.kuaishou.com',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36'
    }

    urlstr = '76买两条鲟鱼,大冬做红烧鲟鱼,先炸再炖,太香了 https://v.kuaishou.com/7ZPRRv 复制此消息,打开【快手】直接观看!'
    url = 'http' + re.findall(r'http(.*?)复制',urlstr)[0]

    r = requests.get(url=url,headers=headers).text
    find_true_url = 'http' + re.findall(r'<td>http(.*?)</td>',r)[0]
    true_url = find_true_url.replace('v.kuaishou.com','video.kuaishou.com')
    print(true_url)

结果如下:

python 爬虫 爬取快手短视频无水印视频解析最新版
那么就可以通过这个链接 利用前面的步骤找到json数据,再找到视频url,再保存就大功告成了,
至此我们的分析就完成了
完整代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2020/12/8 12:58
# @Author  : huni
# @File    : 快手视频爬取.py
# @Software: PyCharm
import requests
import os
import json
import re

if __name__ == '__main__':
    headers1 = {
        'Host': 'v.kuaishou.com',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36'
    }

    urlstr = input('输入视频链接:  ')
    url = 'http' + re.findall(r'http(.*?)复制',urlstr)[0]

    r = requests.get(url=url,headers=headers1).text
    find_true_url = 'http' + re.findall(r'<td>http(.*?)</td>',r)[0]
    true_url = find_true_url.replace('v.kuaishou.com','video.kuaishou.com')
    photoid = true_url.split('?')[-2].split('/')[-1]

    data = {"operationName": "visionVideoDetail", "variables": {"photoId": "", "page": "selected"},
        "query": "query visionVideoDetail($photoId: String, $type: String, $page: String) {\n  visionVideoDetail(photoId: $photoId, type: $type, page: $page) {\n    status\n    type\n    author {\n      id\n      name\n      following\n      headerUrl\n      __typename\n    }\n    photo {\n      id\n      duration\n      caption\n      likeCount\n      realLikeCount\n      coverUrl\n      photoUrl\n      liked\n      timestamp\n      expTag\n      llsid\n      __typename\n    }\n    tags {\n      type\n      name\n      __typename\n    }\n    commentLimit {\n      canAddComment\n      __typename\n    }\n    llsid\n    __typename\n  }\n}\n"}
    data["variables"]["photoId"] = photoid

    json_url = 'https://video.kuaishou.com/graphql'
    headers2 = {
            'content-type': 'application/json',
            'Host': 'video.kuaishou.com',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36'
        }
    data1 = json.dumps(data)
    resp = requests.post(url=json_url,headers=headers2,data=data1).json()
    mp4url = resp['data']['visionVideoDetail']['photo']['photoUrl']

    headers0 = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36'
    }
    mp4data = requests.get(url=mp4url,headers=headers0).content

    mp4name = mp4url.split('?')[-2].split('_b_')[-1]
    title_path = './快手'
    if not os.path.exists(title_path):
        os.mkdir(title_path)
    mp4path = title_path + '/' + mp4name
    with open(mp4path,'wb') as fp:
        fp.write(mp4data)

本文地址:https://blog.csdn.net/m0_50944918/article/details/110875995