全国免费咨询热线

13988889999

工作时间:周一到周六 AM8:30

四方资讯

NEWS

四方资讯

你的位置: 首页 > 四方资讯

联系我们

CONTACT

手机:13988889999
电话:0898-88889999
QQ:88889999
邮箱:admin@eyoucms.com
地址:海南省海口市玉沙路58号

Python爬虫:抖音APP无水印视频批量下载方法详解

时间:2024-01-08 21:51:39    点击量:

本文为两类人准备:技术控和工具控。

抖音短视频解析下载平台

Python3批量下载抖音无水印视频

本文的代码已经不是最新的,但是抓取思路就是如此,可以参考,代码可以直接运行使用,持续维护中

抖音越来越火,感觉它有毒,越刷越上瘾,总感觉下一个视频一定会更精彩,根本停不下来。想将抖音里喜欢的小哥哥/小姐姐的视频全部存到电脑硬盘里该如何操作?不想有抖音的视频水印该如何处理?

当初写完代码的截屏:


?
注意,光理论是不够的。这里顺便送大家一套2020最有趣的Pyhon项目实战视频教程,点击此处 进来获取 跟着练习下,希望大家一起进步哦!

目录

一、前言

更新日志

二、实战背景

三、实战

1、带水印视频下载

2、无水印视频下载

四、总结


进来获取 跟着练习下,希望大家一起进步哦!

首先,希望你已经具备手机APP抓包分析的能力,如果不会请去自行学习:点击跳转

先说说带水印的视频如何抓去吧。在定好爬取目标的时候,我们应该知道自己需要那些步骤完成这项任务。比如本文中提到的任务:抖音APP固定用户的视频批量下载

思考过程:

瞧,这样思考下来,问题是不是梳理的很清楚?

搜索接口:

那么接下来就是抓包分析了,抓包过程请自行尝试。步骤是这样的:

通过分析你会发现,我们通过搜索接口返回的JSON数据可以找到用户主页信息,接下里用同样的方法抓取主页用户信息再分析一波,这时候就遇到问题了,你会发现用户主页链接使用了as和cp参数进行了加密,这该如何是好?比如

Python

aweme.snssdk.com/aweme/

上述链接省略号部分是一些手机信息,这部分不是必须参数,可以省略。user_id是用户id可以通过上个搜索接口获取,count是用户视频数量,同样可以通过上个搜索接口获取。那最后的as和cp参数怎么办?

我没有逆向抖音APP,就是小小测试了一下,看看能不能绕过这个加密接口?抖音APP自带视频分享功能,分享链接Python

douyin.com/share/video/

中间参数都不重要,在此省略。douyin.com域名下存放的是分享的视频,那么这个用户主页信息是否可以通过这个域名进行访问呢?小小测试一下你会发现,完全没有问题!

Python

douyin.com/aweme/v1/awe

这就是没有加密的接口,惊不惊喜,意不意外?根据这个用户主页接口,我们就可以轻松获取用户主页所有的视频链接了。

方法一:

无水印视频下载很简单,有一个通用的方法,就是使用去水印平台即可。

我使用的去水印平台是:douyin.iiilab.com/

在输入框中输入视频链接点击视频解析,就可以获得无水印视频链接。

这个网站当初我写代码的时候是好使的,当初用这个网站下了一些无水印视频,不过写这篇文章的时候发现这个取水印平台无法正常解析了,等它修复好了再用这个功能吧。

这个平台不仅包括抖音视频去水印,还支持火山、快手、陌陌、美拍等无水印视频。所以做一个这个网站的接口还是很合适的。

简单测试了一下,这个网站的API是需要付费解析的,如果通过模拟请求的方式有些困难,因此决定上浏览器模拟器Splinter。

Splinter是个好东西,跟Selenium使用类似,它的配置可以参考我的早期Selenium文章:blog.csdn.net/c40649576

Splinter有个很详细的英文文档:splinter.readthedocs.io

这里使用方法就不累述,不过有一点可以说的是,我们可以配置headless参数,来将Splinter配置为无头浏览器,啥事无头浏览器呢?就是运行Splinter不调出浏览器界面,直接在后台模拟各种请求,很是方便。

这部分的代码很简单,无非就是填充元素,确定解析按钮位置,点击按钮,获取视频下载链接即可。这点小问题,就自行分析吧。

整体代码

Python


# -*- coding:utf-8 -*-

from splinter.driver.webdriver.chrome import Options, Chrome

from splinter.browser import Browser

from contextlib import closing

import requests, json, time, re, os, sys, time

from bs4 import BeautifulSoup


class DouYin(object):

def __init__(self, width=500, height=300):

"""

抖音App视频下载

"""

# 无头浏览器

chrome_options=Options()

chrome_options.add_argument('user-agent="Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"')

self.driver=Browser(driver_name='chrome', executable_path='D:/chromedriver', options=chrome_options, headless=True)


def get_video_urls(self, user_id):

"""

获得视频播放地址

Parameters:

user_id:查询的用户ID

Returns:

video_names: 视频名字列表

video_urls: 视频链接列表

nickname: 用户昵称

"""

video_names=[]

video_urls=[]

unique_id=''

while unique_id !=user_id:

search_url='api.amemv.com/aweme/v1/*1920&dpi=480&update_version_code=1622' % user_id

req=requests.get(url=search_url, verify=False)

html=json.loads(req.text)

aweme_count=html['user_list'][0]['user_info']['aweme_count']

uid=html['user_list'][0]['user_info']['uid']

nickname=html['user_list'][0]['user_info']['nickname']

unique_id=html['user_list'][0]['user_info']['unique_id']

user_url='douyin.com/aweme/v1/awe' % (uid, aweme_count)

req=requests.get(url=user_url, verify=False)

html=json.loads(req.text)

i=1

for each in html['aweme_list']:

share_desc=each['share_info']['share_desc']

if '抖音-原创音乐短视频社区'==share_desc:

video_names.append(str(i) + '.mp4')

i +=1

else:

video_names.append(share_desc + '.mp4')

video_urls.append(each['share_info']['share_url'])


return video_names, video_urls, nickname


def get_download_url(self, video_url):

"""

获得带水印的视频播放地址

Parameters:

video_url:带水印的视频播放地址

Returns:

download_url: 带水印的视频下载地址

"""

req=requests.get(url=video_url, verify=False)

bf=BeautifulSoup(req.text, 'lxml')

script=bf.find_all('script')[-1]

video_url_js=re.findall('var data=\\[(.+)\\];', str(script))[0]

video_html=json.loads(video_url_js)

download_url=video_html['video']['play_addr']['url_list'][0]

return download_url


def video_downloader(self, video_url, video_name, watermark_flag=False):

"""

视频下载

Parameters:

video_url: 带水印的视频地址

video_name: 视频名

watermark_flag: 是否下载不带水印的视频

Returns:

"""

size=0

if watermark_flag==True:

video_url=self.remove_watermark(video_url)

else:

video_url=self.get_download_url(video_url)

with closing(requests.get(video_url, stream=True, verify=False)) as response:

chunk_size=1024

content_size=int(response.headers['content-length'])

if response.status_code==200:

sys.stdout.write('[文件大小]:%0.2f MB\ ' % (content_size / chunk_size / 1024))


with open(video_name, "wb") as file:

for data in response.iter_content(chunk_size=chunk_size):

file.write(data)

size +=len(data)

file.flush()


sys.stdout.write('[下载进度]:%.2f%%' % float(size / content_size * 100) + '\\r')

sys.stdout.flush()



def remove_watermark(self, video_url):

"""

获得无水印的视频播放地址

Parameters:

video_url: 带水印的视频地址

Returns:

无水印的视频下载地址

"""

self.driver.visit('douyin.iiilab.com/')

self.driver.find_by_tag('input').fill(video_url)

self.driver.find_by_xpath('//button[@class="btn btn-default"]').click()

html=self.driver.find_by_xpath('//div[@class="thumbnail"]/div/p')[0].html

bf=BeautifulSoup(html, 'lxml')

return bf.find('a').get('href')


def run(self):

"""

运行函数

Parameters:

None

Returns:

None

"""

self.hello()

user_id=input('请输入ID(例如40103580):')

video_names, video_urls, nickname=self.get_video_urls(user_id)

if nickname not in os.listdir():

os.mkdir(nickname)

print('视频下载中:共有%d个作品!\ ' % len(video_urls))

for num in range(len(video_urls)):

print(' 解析第%d个视频链接[%s]中,请稍后!\ ' % (num+1, video_urls[num]))

if '\\\\' in video_names[num]:

video_name=video_names[num].replace('\\\\', '')

elif '/' in video_names[num]:

video_name=video_names[num].replace('/', '')

else:

video_name=video_names[num]

self.video_downloader(video_urls[num], os.path.join(nickname, video_name))

print('\ ')


print('下载完成!')


def hello(self):

"""

打印欢迎界面

Parameters:

None

Returns:

None

"""

print('*' * 100)

print('\ \ \ \ 抖音App视频下载小助手')

print('\ \ 作者:Jack Cui')

print('*' * 100)



if __name__=='__main__':

douyin=DouYin()

douyin.run()

方法二:

这个方法是通过网友@羽葵的反馈得知的,对下载链接直接修改即可得到无水印下载链接。


Python


1

download_url=video_html['video']['play_addr']['url_list'][0].replace('playwm','play')

方法简单粗暴,很好用。好处就是处理速度飞快,缺点是这种方法通用性不强,不同视频发布平台的打码方法可能有不同,需要自行分析。

玩爬虫的日子还是很有意思的,好久没有那种舒爽感了。还有,找工作也是蛮心累的事。最后送大家一套2020最有趣的Pyhon项目实战视频教程,点击此处 进来获取 跟着练习下,希望大家一起进步哦!
?本文的文字及图片来源于网络加上自己的想法,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。

地址:海南省海口市玉沙路58号 电话:0898-88889999 手机:13988889999

Copyright © 2012-2018 首页-四方娱乐-注册登录站 ICP备案编:琼ICP备88889999号

友情链接: 大唐金牛九天凯旋

平台注册入口