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

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

在这里插入图片描述
但是打开之后发现一些端倪,视频可以正常看,但是url变了不是原来的url了,

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

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

进入正题:

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

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

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

python 爬虫 爬取快手短视频无水印视频解析最新版_第5张图片
并且视频不带快手的水印


然后咱们先测试一下,看看使用代码请求这段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 爬虫 爬取快手短视频无水印视频解析最新版_第6张图片
那么我们就知道啦,只要得到这个json数据,在提取出里面的url就可以下载无水印的视频了,

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

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

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

python 爬虫 爬取快手短视频无水印视频解析最新版_第7张图片
那么我们是以下看看能不能通过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 爬虫 爬取快手短视频无水印视频解析最新版_第8张图片
然后经过提取获得完整的url

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

就是这个东西

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

在这里插入图片描述
那么我们回到了之前的问题怎么转成这个链接呢

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

python 爬虫 爬取快手短视频无水印视频解析最新版_第11张图片
请求头里的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'http(.*?)',r)[0]
    true_url = find_true_url.replace('v.kuaishou.com','video.kuaishou.com')
    print(true_url)

结果如下:

在这里插入图片描述
那么就可以通过这个链接 利用前面的步骤找到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'http(.*?)',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)

你可能感兴趣的:(爬虫,python,json,post,大数据,机器学习)