要素过多建议收藏
首先打开复制的一个链接
发现复制直接打开到浏览器不行,不是我们想要的内容,
然后我们就复制这个里面的url部分打开浏览器就可以了
但是打开之后发现一些端倪,视频可以正常看,但是url变了不是原来的url了,
首先先找到视频的url ,按照惯例,通常视频的url链接不会出现在网页源码中,一种可能是通过分段的视频文件动态加载再进行合成,这种方式常被用于长视频之类的,比如哔哩哔哩,腾讯视频等,快手这种短的几分钟的视频通常会把视频的url储存在json数据里面,当然哔哩哔哩也会有采用形式的视频,在之前项目中有遇到过,
进入正题:
首先打开抓包工具,刷新下页面
百度搜索json在线解析工具,复制这段json进行解析,方便查看
然后咱们先测试一下,看看使用代码请求这段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)
运行之后,打开文件夹发现可以播放,且无水印跟刚才一样
那么我们就知道啦,只要得到这个json数据,在提取出里面的url就可以下载无水印的视频了,
那么问题来了们如何获取这个json呢?往下看
打开抓包工机看这个headers观察看看
发现是个post请求,并且需要传递payload参数
那么我们是以下看看能不能通过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数据
然后我们发现,现在的问题是我们需要将每个data里面的photoid 换成我们想要提取的视频的id ,其他不变
就是这个东西
我们再次复制打开啊发现这里有个小细节
请求头里的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)