文章目录
- 写在前面需求开始分析解决方案去除水印完整代码
私信小编01即可获取大量Python学习资料
写在前面
非逆向破解_signature!非逆向破解_signature!非逆向破解_signature!订阅前请谨慎。
抖音更新频繁,不保证长期有效,有效日期会在标题写出。
本文仅限交流学习使用, 请勿使用在任何非法商业活动。
需求
某天,一朋友甩给我一张图片(下图)和一个视频分享链接(如下)
山西方言在内蒙古居然可以畅通无阻?“焖当户对面”送给大家... #贫穷料理 #美食趣胃计划 https://v.douyin.com/JA77fMD/ 复制此链接,打开【抖音短视频】,直接观看视频!
问我能不能拿到无水印的视频文件
开始分析
我们按常规套路一步步来:
打开网址,F12先分析一下网页请求
首先看到短链接被302重定向到视频播放页的链接。
视频播放页的链接返回完整的网页代码
https://www.iesdouyin.com/share/video/6874779817993276685/?region=CN&mid=6874780172541774599&u_code=16j6jj9bf&titleType=title×tamp=1600844701&utm_campaign=client_share&app=aweme&utm_medium=ios&tt_from=copy&utm_source=copy
另外一个接口返回了视频相关的数据
https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids=6874779817993276685
目测 item_ids 就是视频编号,这个接口并不需要 _signature、dytk 等复杂参数,非常简单。
解决方案
看到这里就首先想到了两个解决方案:
- 使用 selenium 或 puppeteer 直接访问短链接,模拟点击“播放”键后,从网页中用 xpath 或 re 或其他你喜欢的方式匹配出视频文件链接。
-
获取 item_ids 参数,直接访问接口 “https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids=” 拿到视频数据,提取出视频文件链接。
考虑到这个接口很简单,参数也很好获取,我个人采取的方案二:
对比一下链接发现,item_ids 可以在短链接重定向是直接获取
https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids=6874779817993276685
https://www.iesdouyin.com/share/video/6874779817993276685/?region=CN&mid=6874780172541774599&u_code=16j6jj9bf&titleType=title×tamp=1600844701&utm_campaign=client_share&app=aweme&utm_medium=ios&tt_from=copy&utm_source=copy
# 电脑UA访问短链接,通过302重定向时response.headers中的location标签获取视频id号
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36', }
response = requests.get(url=shrot_video_url, headers=headers, allow_redirects=False)
items_ids = re.findall(r'video/(.*?)/', response.headers['location'])[0]
# 电脑UA访问官方api视频分享接口,获取视频播放链接
url = 'https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids={}'.format(items_ids)
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36', }
response = requests.get(url=url, headers=headers)
play_addr = response.json().get('item_list')[0]['video']['play_addr']['url_list'][0]
去除水印
我们拿到的视频文件链接链接如下:
# 有水印
https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f9a0000btk1rt9c21acl8d6vjl0&ratio=720p&line=0
这个链接还是有水印的,我们只需要把链接中的 “playwm” 改为 “play”,即可变为无水印的。
(wm是watermark “水印” 的缩写,不止抖音,其他平台也有用到)
# 无水印
https://aweme.snssdk.com/aweme/v1/play/?video_id=v0300f9a0000btk1rt9c21acl8d6vjl0&ratio=720p&line=0
当我们用手机UA访问上面链接时,发现又会跳转一次
http://v5-dy-d.ixigua.com/a181ba8f34818155b859b70c8b518643/5f70462f/video/tos/cn/tos-cn-ve-15/a0f9a89ec46b4cad83e8cd9215129521/?a=1128&br=6237&bt=2079&cr=0&cs=0&cv=1&dr=0&ds=3&er=&l=202009271456590101980601475921B6A9&lr=&mime_type=video_mp4&qs=0&rc=M205O2Y0Znc0dzMzZGkzM0ApNWVlPDtpOWRpNzU5ZTM7Omdpc2FpXi82b2hfLS02LTBzczAvNTQtXjMvLy4wLy4vYi46Yw%3D%3D&vl=&vr=
好了,现在可以下载视频了
完整代码
def download_video(shrot_video_url):
# 电脑UA访问短链接,通过302重定向时response.headers中的location标签获取视频id号
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36', }
response = requests.get(url=shrot_video_url, headers=headers, allow_redirects=False)
items_ids = re.findall(r'video/(.*?)/', response.headers['location'])[0]
# 电脑UA访问官方api视频分享接口,获取视频播放链接,通过替换 playwm 为 play 后,得到无水印的视频播放连接
url = 'https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids={}'.format(items_ids)
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36', }
response = requests.get(url=url, headers=headers)
play_addr = response.json().get('item_list')[0]['video']['play_addr']['url_list'][0]
play_addr_nowm = str(play_addr).replace('playwm', 'play')
print(play_addr_nowm)
# 手机UA访问无水印的视频播放链接,经过302重定向后,获取无水印视频播放真实链接 (注意:此处若使用电脑UA则获取不到任何数据)
headers = {'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1', }
response = requests.get(url=play_addr_nowm, headers=headers, allow_redirects=False)
real_play_addr_nowm = response.headers['location']
print(real_play_addr_nowm)
# 手机UA访问,下载视频 (注意:此处若使用电脑UA则获取不到任何数据)
headers = {
'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1',
'Connection': 'keep-alive',
'Host': 'v5-dy-d.ixigua.com'
}
r = requests.get(url=real_play_addr_nowm, headers=headers, stream=True)
# 下载视频
print("{}开始下载".format(items_ids))
with open('{}.mp4'.format(items_ids), "wb") as mp4:
for chunk in r.iter_content(chunk_size=1024 * 1024):
if chunk:
mp4.write(chunk)
print("{}下载结束".format(items_ids))
if __name__ == '__main__':
# 单个视频分享页————下载无水印视频
video_list = ['https://v.douyin.com/JA77fMD/']
for j in video_list:
download_video(j)