Skip to content

Commit 54c9d32

Browse files
authored
抖音app视频下载升级版
抖音app视频下载升级版
1 parent 38e7e61 commit 54c9d32

File tree

1 file changed

+159
-0
lines changed

1 file changed

+159
-0
lines changed

douyin_pro.py

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
# -*- coding:utf-8 -*-
2+
from splinter.driver.webdriver.chrome import Options, Chrome
3+
from splinter.browser import Browser
4+
from contextlib import closing
5+
import requests, json, time, re, os, sys, time
6+
from bs4 import BeautifulSoup
7+
8+
class DouYin(object):
9+
def __init__(self, width = 500, height = 300):
10+
"""
11+
抖音App视频下载
12+
"""
13+
# 无头浏览器
14+
chrome_options = Options()
15+
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"')
16+
self.driver = Browser(driver_name='chrome', executable_path='D:/chromedriver', options=chrome_options, headless=True)
17+
18+
def get_video_urls(self, user_id):
19+
"""
20+
获得视频播放地址
21+
Parameters:
22+
user_id:查询的用户ID
23+
Returns:
24+
video_names: 视频名字列表
25+
video_urls: 视频链接列表
26+
nickname: 用户昵称
27+
"""
28+
video_names = []
29+
video_urls = []
30+
unique_id = ''
31+
while unique_id != user_id:
32+
search_url = 'https://api.amemv.com/aweme/v1/discover/search/?cursor=0&keyword=%s&count=10&type=1&retry_type=no_retry&iid=17900846586&device_id=34692364855&ac=wifi&channel=xiaomi&aid=1128&app_name=aweme&version_code=162&version_name=1.6.2&device_platform=android&ssmix=a&device_type=MI+5&device_brand=Xiaomi&os_api=24&os_version=7.0&uuid=861945034132187&openudid=dc451556fc0eeadb&manifest_version_code=162&resolution=1080*1920&dpi=480&update_version_code=1622' % user_id
33+
req = requests.get(url = search_url, verify = False)
34+
html = json.loads(req.text)
35+
aweme_count = html['user_list'][0]['user_info']['aweme_count']
36+
uid = html['user_list'][0]['user_info']['uid']
37+
nickname = html['user_list'][0]['user_info']['nickname']
38+
unique_id = html['user_list'][0]['user_info']['unique_id']
39+
user_url = 'https://www.douyin.com/aweme/v1/aweme/post/?user_id=%s&max_cursor=0&count=%s' % (uid, aweme_count)
40+
req = requests.get(url = user_url, verify = False)
41+
html = json.loads(req.text)
42+
i = 1
43+
for each in html['aweme_list']:
44+
share_desc = each['share_info']['share_desc']
45+
if '抖音-原创音乐短视频社区' == share_desc:
46+
video_names.append(str(i) + '.mp4')
47+
i += 1
48+
else:
49+
video_names.append(share_desc + '.mp4')
50+
video_urls.append(each['share_info']['share_url'])
51+
52+
return video_names, video_urls, nickname
53+
54+
def get_download_url(self, video_url):
55+
"""
56+
获得带水印的视频播放地址
57+
Parameters:
58+
video_url:带水印的视频播放地址
59+
Returns:
60+
download_url: 带水印的视频下载地址
61+
"""
62+
req = requests.get(url = video_url, verify = False)
63+
bf = BeautifulSoup(req.text, 'lxml')
64+
script = bf.find_all('script')[-1]
65+
video_url_js = re.findall('var data = \[(.+)\];', str(script))[0]
66+
video_html = json.loads(video_url_js)
67+
download_url = video_html['video']['play_addr']['url_list'][0]
68+
return download_url
69+
70+
def video_downloader(self, video_url, video_name, watermark_flag=True):
71+
"""
72+
视频下载
73+
Parameters:
74+
video_url: 带水印的视频地址
75+
video_name: 视频名
76+
watermark_flag: 是否下载不带水印的视频
77+
Returns:
78+
79+
"""
80+
size = 0
81+
if watermark_flag == True:
82+
video_url = self.remove_watermark(video_url)
83+
else:
84+
video_url = self.get_download_url(video_url)
85+
with closing(requests.get(video_url, stream=True, verify = False)) as response:
86+
chunk_size = 1024
87+
content_size = int(response.headers['content-length'])
88+
if response.status_code == 200:
89+
sys.stdout.write(' [文件大小]:%0.2f MB\n' % (content_size / chunk_size / 1024))
90+
91+
with open(video_name, "wb") as file:
92+
for data in response.iter_content(chunk_size = chunk_size):
93+
file.write(data)
94+
size += len(data)
95+
file.flush()
96+
97+
sys.stdout.write(' [下载进度]:%.2f%%' % float(size / content_size * 100) + '\r')
98+
sys.stdout.flush()
99+
100+
101+
def remove_watermark(self, video_url):
102+
"""
103+
获得无水印的视频播放地址
104+
Parameters:
105+
video_url: 带水印的视频地址
106+
Returns:
107+
无水印的视频下载地址
108+
"""
109+
self.driver.visit('http://douyin.iiilab.com/')
110+
self.driver.find_by_tag('input').fill(video_url)
111+
self.driver.find_by_xpath('//button[@class="btn btn-default"]').click()
112+
html = self.driver.find_by_xpath('//div[@class="thumbnail"]/div/p')[0].html
113+
bf = BeautifulSoup(html, 'lxml')
114+
return bf.find('a').get('href')
115+
116+
def run(self):
117+
"""
118+
运行函数
119+
Parameters:
120+
None
121+
Returns:
122+
None
123+
"""
124+
self.hello()
125+
user_id = input('请输入ID(例如40103580):')
126+
video_names, video_urls, nickname = self.get_video_urls(user_id)
127+
if nickname not in os.listdir():
128+
os.mkdir(nickname)
129+
print('视频下载中:共有%d个作品!\n' % len(video_urls))
130+
for num in range(len(video_urls)):
131+
print(' 解析第%d个视频链接 [%s] 中,请稍后!\n' % (num+1, video_urls[num]))
132+
if '\\' in video_names[num]:
133+
video_name = video_names[num].replace('\\', '')
134+
elif '/' in video_names[num]:
135+
video_name = video_names[num].replace('/', '')
136+
else:
137+
video_name = video_names[num]
138+
self.video_downloader(video_urls[num], os.path.join(nickname, video_name))
139+
print('\n')
140+
141+
print('下载完成!')
142+
143+
def hello(self):
144+
"""
145+
打印欢迎界面
146+
Parameters:
147+
None
148+
Returns:
149+
None
150+
"""
151+
print('*' * 100)
152+
print('\t\t\t\t抖音App视频下载小助手')
153+
print('\t\t作者:Jack Cui')
154+
print('*' * 100)
155+
156+
157+
if __name__ == '__main__':
158+
douyin = DouYin()
159+
douyin.run()

0 commit comments

Comments
 (0)