引言
上篇文章讲到抖音首页视频的爬取和下载,于是我想到能不能下载特定的视频。网上搜索一番,发现有网站提供抖音无水印视频的下载,但是试了几个,发现下载下来都还是有水印的视频。上篇文章已经实现了首页无水印视频的下载,于是想自己建一个网站实现一下指定视频的无水印下载。参考现有的网站,实现的思路都是输入为抖音的分享链接,输出为无水印视频,我也参照这一思路,实现了效果。在此记录一下过程中遇到的问题。
网站
思路
- 从抖音分享链接拿到视频ID
- 根据视频ID拿到无水印视频下载地址
- 下载视频
- 建站
问题
1. 从分享链接中如何获取视频ID
抖音的分享链接为http://v.douyin.com/xxx/,抓包没有发现这个url,发现最开始的url为https://www.iesdouyin.com/share/video/6629644890483461380/…,这个6629644890483461380就是视频ID,猜测这个url是从http://v.douyin.com/xxx/重定向来的。在Fiddler里get这个url,发现Headers里的Location就是上面的url。
然后正则表达式从url里把视频ID取出来就好了,代码如下:
def get_aweme_id(self, share_url): # 调用接口,根据share_url获取aweme_id
# 真实url为headers里的Location,禁止重定向,才能获取
r = requests.get(share_url, headers=self.headers, allow_redirects=False)
url = r.headers['Location']
aweme_id = re.search(r'\d+', url).group()
return aweme_id
2. 找到指定视频的post接口
有了视频ID,下面就是要找到将这个视频ID post给哪个接口才能获取对应视频信息。尝试抓包抖音的搜索功能,发现根据视频ID无法搜索到对应视频,使用过程中抓包也没有发现对应的接口。最后Google了半天,找到了对应的接口url:https://aweme.snssdk.com/aweme/v1/aweme/detail/
url参数如下(样例):
Name | Value | Description |
---|---|---|
iid | 51050168070 | 设备信息 |
idfa | 887748FC-0DA1-4984-B87F-F2FC9AC5D14B | 设备信息 |
device_type | iPhone5,2 | 设备信息 |
os_version | 10.3.3 | 设备信息 |
screen_width | 640 | 设备信息 |
vid | AECABC99-0F66-4086-86BC-EC4E01B4DEA1 | 设备信息 |
device_id | 59415024289 | 设备信息 |
os_api | 18 | 设备信息 |
device_platform | iphone | 设备信息 |
openudid | 75a4bc255848cd7901e166e5c168b23e3e9394a8 | 设备信息 |
version_code | 3.1.0 | app信息 |
aid | 1128 | app信息 |
app_name | aweme | app信息 |
build_number | 31006 | app信息 |
app_version | 3.1.0 | app信息 |
channel | App Store | app信息 |
pass-region | 1 | 常量 |
js_sdk_version | 1.3.0.1 | 常量 |
ac | mobile | 常量 |
mas | 0161b6c4a20babcf6829e30950a9f3a577adb04abc0c6da0eeca91 | 加密参数 |
as | a105e18ff4e32b1a102320 | 加密参数 |
ts | 1542462004 | 加密参数 |
post参数如下(样例):
Name | Value | Description |
---|---|---|
aweme_id | 6629644890483461380 | 视频ID |
加密参数上篇文章有讲到,这里就不赘述了。将所需要的参数发送给接口,即可返回指定视频信息,从其中拿到无水印视频下载地址。
3. 建站相关问题
下载地址拿到了,直接requests下载即可。逻辑功能都是实现了,下面就是建站了。本来以为建站很简单,结果发现在这上面花费时间是最多的。
(1). Django中的参数如何传递给JS
Python web最常用的是Django,那就学习一下Django怎么开发web。整个Django的逻辑很快入了门,但是花费时间最多的还是在前端。因为没有前端基础再加上也不想搞前端,写前端代码真是头痛。不过最后还是挺顺利,虽然花费了很多时间,就有一个问题卡了一下。Django的view中参数怎么传递给html中的JS里。像正常的一样,利用context字典传过去,在JS中{{ }}引用行不通。
解决:
Django传递给参数给JS,context中的value需要用json.dumps()处理之后,才能给对应的key。另外在JS中引用需要用safe过滤,代码如下:
view.py
.......
# 这里要用json.dumps传递参数,html的js里才能用{{download_url|safe}}引用该变量
context['download_url'] = json.dumps(download_url)
context['desc'] = json.dumps(desc)
......
douyin.html
......
<script type="text/javascript">
function download(){
window.open({{ download_url|safe }});
}
</script>
......
(2). 下载地址在浏览器打开报错403
拿到下载地址后,本来应该弹出下载框进行下载,但是因为实在不想写前端代码了,直接在新窗口打开这个地址,让用户自己进行手动下载。代码如下:
<script type="text/javascript">
function download(){
window.open({{ download_url|safe }});
}
</script>
但是发现在360浏览器会直接弹出下载框,但是在chrome浏览器里新打开的窗口就会报错403。
解决:
将地址栏手动复制到新窗口打开
(3). 服务器部署过程中的问题
这里也踩了很多坑,因为不熟悉,最开始是用apache部署Django,但是我按照网上教程部署好之后,访问不通,而且感觉配置有点复杂,最后就换了nginx部署,按照这个教程 python3 + Django + uwsgi + nginx 配置部署笔记 一遍就搞定了。
总结
爬虫免不了和前端打交道,还是要抽时间系统的学习下前端知识。