如何爬取抖音小视频

抖音上面有许多精彩有趣的视频,如果我们想把这些短视频下载下来离线观看的话,该怎么写爬虫呢?现在全国人民都在抗击新型肺炎,可惜我不是医生,也帮不上忙,与其整天刷手机,惶惶终日,不如写写代码,学点儿东西。

主要思路

在google的帮助下,终于找到一个思路。
利用fiddler和模拟器来抓取抖音和后台之间的https数据包,将其中的视频的地址提取出来,再利用python对这些视频进行下载保存。
思路很简单,但是这个环境的搭建并不容易,浪费了不少时间。

开发环境

  • win10 x64
  • Fiddler 一个http代理工具,用于进行软件测试
  • 雷电模拟器
  • vscode 用于编辑代码
  • python3.7 (Anaconda 3)

fiddler的安装和配置

从fiddler的官网(https://www.telerik.com/fiddler)下载最新版本安装。
以管理员权限运行
在Tools->Options中进行如下配置

图片.png

图片.png

点击界面右上角的Online会显示出代理的IP地址。
重启fiddler.

雷电模拟器的安装和配置

在雷电模拟器的官网(https://www.ldmnq.com/)上下载安装。
打开雷电模拟器,安装抖音app

配置网络

在设置->WLAN,找到已经连接的wifi,长按,点击修改网络


修改网络.png

勾选高级设置
设置静态的IP地址和代理IP和端口,注意手机的IP地址要与本机的地址在同一网段内,代理的地址为前文中fiddler中显示的地址,一般为本地的地址。如下图所示。


设置代理

设置网络后重启模拟器。

安装https证书

在浏览器中打开https://[proxy_ip:proxy_port],打开如下页面。


安装证书.png

下载并安装证书,安装过程中需要为证书命名并设置开机密码。然后重启。

Fiddler抓包

如果上面的环境搭建过程没有问题的话,在fiddler中就可以看到app的中数据包了。
比如在抖音中打开"私人飞机花生哥"的主页,下面列出了他的作品。在fiddler中可以看到app向后台的发现的https请求包。


Fiddler抓包

aweme_list中含有视频的播放和下载地址。


image.png

通过观察不难发现,随着向上滑动,会有多次这个请求,每次都会返回一些视频信息,如果一直滑到底的话,这个作者的所有作品信息都可以拿到了。

下面我们利用这一点,利用fiddler将视频这些请求以文本形式保存下来。
在菜单Rules->Customize Rules,打开fidder脚本编辑器。


自定义规则

跳转到OnBeforeRequest函数,该函数可拦截requests。


定位到OnBeforeRequest函数

添加如下js代码。
//过滤无关请求,只关注特定请求
if (oSession.fullUrl.Contains("aweme.snssdk.com/aweme/v1/aweme/post"))
{
    var fso;
    var file;
    fso = new ActiveXObject("Scripting.FileSystemObject");
    //文件保存路径,可自定义
    file = fso.OpenTextFile("D:\\douyin\\requests.txt",8 ,true, true);
    file.writeLine("Request url: " + oSession.url);
    file.writeLine("Request header:" + "\n" + oSession.oRequest.headers);
    file.writeLine("Request body: " + oSession.GetRequestBodyAsString());
    file.writeLine("\n");
    file.close();
}

定位到OnBeforeResponse函数,该函数用于拦截response,添加如下js代码。

//过滤无关请求,只关注特定请求
if (oSession.fullUrl.Contains("aweme.snssdk.com/aweme/v1/aweme/post"))
{
    //oSession.utilDecodeResponse();//消除保存的请求可能存在乱码的情况
    var fso;
    var file;
    fso = new ActiveXObject("Scripting.FileSystemObject");
    //文件保存路径,可自定义
    file = fso.OpenTextFile("D:\\douyin\\response.txt",8 ,true, true);
    file.writeLine(oSession.GetResponseBodyAsString());
    file.writeLine("+++++++++");
    file.close();
}

这样会将所有url中含有aweme.snssdk.com/aweme/v1/aweme/post的请求和响应都以追加形式保存为文本文件。其中响应以''+++++++++''进行分割。
下面测试一下,删除requests.txt和response.txt文件,在模拟器将这个作者主页滑动到最下面,fiddler会将所有的请求都保存在requests.txt中,将所有的响应都保存在response.txt文件中。
response为一个json格式,其内容为

{
    ...
    "aweme_list": [
        {
            "aweme_id": "6754926284817698060",
            "desc": "什么是热障? @全球飞机榜  @抖音小助手  #干货都在这",
            ...
            "video": {
                ...
                "download_addr": {
                    "uri": "v0200ff80000bmv538fff778hm097jog",
                    "url_list": [
                        "https://aweme.snssdk.com/aweme/v1/play/?video_id=v0200ff80000bmv538fff778hm097jog\u0026line=0\u0026ratio=540p\u0026watermark=1\u0026media_type=4\u0026vr_type=0\u0026improve_bitrate=0\u0026logo_name=aweme\u0026quality_type=11\u0026source=PackSourceEnum_PUBLISH",
                        "https://api.amemv.com/aweme/v1/play/?video_id=v0200ff80000bmv538fff778hm097jog\u0026line=1\u0026ratio=540p\u0026watermark=1\u0026media_type=4\u0026vr_type=0\u0026improve_bitrate=0\u0026logo_name=aweme\u0026quality_type=11\u0026source=PackSourceEnum_PUBLISH"
                    ],
                }
                ...
            }
        }
        ...
}

不难发现其中含有短视频的描述信息和下载地址。

下载视频

这里使用python从response.txt文件中提取出每个response,将其中的视频地址提取出来,结合利用requests.txt中的头信息,将这些视频抓取到本地。
代码如下。

#-*- coding:utf-8 -*-
# written by wlj @22:46 2020/1/28
import requests
from requests.packages import urllib3
import json
urllib3.disable_warnings()

def download_video(url,title):
    #这里requests使用的headers信息,其中含有用户鉴权信息和cookie
    #这是从requests.txt文件中拷贝的
    t = """
        Accept-Encoding: gzip
        X-SS-REQ-TICKET: 1580217939813
        sdk-version: 1
        Cookie: odin_tt=42827ad8b1bbc13c0fe69f622c36c075f3d53deb6647e704c8638b16dd45cb822cd9f30f0427ca56160ca283338839d5e18de02ace41a64011d118065abb7c87; install_id=99098965031; ttreq=1$1aac280ead74ddb2d334de2b131dbca9e5eb1df4
        X-Gorgon: 03006cc04001df5db027cc24af666ff154cd415902cc8cae7ff2
        X-Khronos: 1580217939
        Host: aweme.snssdk.com
        Connection: Keep-Alive
        User-Agent: okhttp/3.10.0.1
    """
    #构造headers字典
    headers = {}
    for line in t.strip().split('\n'):
        k,v = line.strip().split(': ')
        headers[k] = v
    #过滤掉title中非法字符
    illege_chars = ['<','>','/','\\','|',':','"','*','?']
    for char in illege_chars:         
        title = title.replace(char,'_')
    #下载视频文件,保存为mp4
    res1 = requests.get(url = url, headers=headers,stream=True,verify=False)
    with open('%s.mp4' % title, "wb") as f:
        for chunk in res1.iter_content(chunk_size=1024):
            if chunk:
                f.write(chunk)

def main():
    #从reponse.txt文件中分离中各个reponse
    #注意fiddler保存的文件不是utf-8编码,需要将其转化为utf-8编码,才能正确读取,推荐使用Notepad++
    data = open('response.txt','r',encoding='utf-8').read().split("+++++++++")[:-1]  
    for x in data:
        x = json.loads(x)
        #从中提取视频信息,包括视频的描述信息和下载地址
        video_list = [(item['video']['download_addr']['url_list'][0],item['desc']) for item in x['aweme_list']]
        for item in video_list:
            #调用download_video下载视频
            download_video(item[0],item[1])
main()

结果

爬取的短视频
本地播放

参考资料

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 230,622评论 6 544
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 99,716评论 3 429
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 178,746评论 0 383
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 63,991评论 1 318
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 72,706评论 6 413
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 56,036评论 1 329
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 44,029评论 3 450
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 43,203评论 0 290
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 49,725评论 1 336
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 41,451评论 3 361
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 43,677评论 1 374
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 39,161评论 5 365
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 44,857评论 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 35,266评论 0 28
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 36,606评论 1 295
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 52,407评论 3 400
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 48,643评论 2 380