@@ -10,14 +10,15 @@ def __init__(self, width = 500, height = 300):
10
10
"""
11
11
抖音App视频下载
12
12
"""
13
- rip = ip_address ('.' . join ( map ( str , ( random . randint ( 0 , 255 ) for _ in range ( 4 )))) )
13
+ rip = ip_address ('0.0.0.0' )
14
14
while rip .is_private :
15
15
rip = ip_address ('.' .join (map (str , (random .randint (0 , 255 ) for _ in range (4 )))))
16
16
self .headers = {
17
17
'accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8' ,
18
18
'accept-encoding' : 'gzip, deflate, br' ,
19
19
'accept-language' : 'zh-CN,zh;q=0.9' ,
20
- 'cache-control' : 'max-age=0' ,
20
+ 'pragma' : 'no-cache' ,
21
+ 'cache-control' : 'no-cache' ,
21
22
'upgrade-insecure-requests' : '1' ,
22
23
'user-agent' : 'Mozilla/5.0 (Linux; U; Android 5.1.1; zh-cn; MI 4S Build/LMY47V) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/53.0.2785.146 Mobile Safari/537.36 XiaoMi/MiuiBrowser/9.1.3' ,
23
24
'X-Real-IP' : str (rip ),
@@ -28,7 +29,7 @@ def get_video_urls(self, user_id):
28
29
"""
29
30
获得视频播放地址
30
31
Parameters:
31
- user_id:查询的用户ID
32
+ user_id:查询的用户UID
32
33
Returns:
33
34
video_names: 视频名字列表
34
35
video_urls: 视频链接列表
@@ -37,48 +38,45 @@ def get_video_urls(self, user_id):
37
38
video_names = []
38
39
video_urls = []
39
40
share_urls = []
40
- unique_id = ''
41
- device_id = str (random .randint (3 , 5 )) + '' .join (map (str , (random .randint (0 , 9 ) for _ in range (10 ))))
42
- search_url = 'https://api.amemv.com/aweme/v1/discover/search/?cursor=0&keyword={0}&count=10&type=1&retry_type=no_retry&device_id={1}&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&manifest_version_code=162&resolution=1080*1920&dpi=480&update_version_code=1622' .format (user_id , device_id )
43
- req = requests .get (search_url , headers = self .headers )
44
- html = json .loads (req .text )
45
- aweme_count = 32767 # html['user_list'][0]['user_info']['aweme_count']
46
- uid = html ['user_list' ][0 ]['user_info' ]['uid' ]
47
- nickname = html ['user_list' ][0 ]['user_info' ]['nickname' ]
48
- unique_id = html ['user_list' ][0 ]['user_info' ]['unique_id' ]
49
- if unique_id != user_id :
50
- unique_id = html ['user_list' ][0 ]['user_info' ]['short_id' ]
51
- if unique_id != user_id :
52
- print ('用户ID可能输入错误或无法搜索到此用户ID' )
53
- sys .exit ()
54
- share_user_url = 'https://www.amemv.com/share/user/%s' % uid
41
+ max_cursor = 0
42
+ has_more = 1
43
+ share_user_url = 'https://www.amemv.com/share/user/%s' % user_id
55
44
share_user = requests .get (share_user_url , headers = self .headers )
56
- _dytk_re = re .compile (r"dytk: '(.+)'" )
45
+ _dytk_re = re .compile (r"dytk:\s* '(.+)'" )
57
46
dytk = _dytk_re .search (share_user .text ).group (1 )
47
+ _nickname_re = re .compile (r'<p class="nickname">(.+?)<\/p>' )
48
+ nickname = _nickname_re .search (share_user .text ).group (1 )
58
49
print ('JS签名下载中' )
59
50
urllib .request .urlretrieve ('https://github.com/Jack-Cherish/python-spider/blob/master/douyin/fuck-byted-acrawler.js' , 'fuck-byted-acrawler.js' )
60
51
try :
61
- process = Popen (['node' , 'fuck-byted-acrawler.js' , str (uid )], stdout = PIPE , stderr = PIPE )
52
+ process = Popen (['node' , 'fuck-byted-acrawler.js' , str (user_id )], stdout = PIPE , stderr = PIPE )
62
53
except (OSError , IOError ) as err :
63
54
print ('请先安装 node.js: https://nodejs.org/' )
64
55
sys .exit ()
65
56
sign = process .communicate ()[0 ].decode ().strip ('\n ' )
66
- user_url = 'https://www.amemv.com/aweme/v1/aweme/post/?user_id=%s&max_cursor=0&count=%s&aid=1128&_signature=%s&dytk=%s' % (uid , aweme_count , sign , dytk )
67
- req = requests .get (user_url , headers = self .headers )
68
- html = json .loads (req .text )
69
- for each in html ['aweme_list' ]:
70
- share_desc = each ['share_info' ]['share_desc' ]
71
- if os .name == 'nt' :
72
- for c in r'\/:*?"<>|' :
73
- nickname = nickname .replace (c , '' ).strip ()
74
- share_desc = share_desc .replace (c , '' ).strip ()
75
- share_id = each ['aweme_id' ]
76
- if share_desc in ['抖音-原创音乐短视频社区' , 'TikTok' ]:
77
- video_names .append (share_id + '.mp4' )
78
- else :
79
- video_names .append (share_id + '-' + share_desc + '.mp4' )
80
- share_urls .append (each ['share_info' ]['share_url' ])
81
- video_urls .append (each ['video' ]['play_addr' ]['url_list' ][0 ])
57
+ print ('解析视频链接中' )
58
+ while has_more != 0 :
59
+ user_url = 'https://www.amemv.com/aweme/v1/aweme/post/?user_id=%s&max_cursor=%s&count=21&aid=1128&_signature=%s&dytk=%s' % (user_id , max_cursor , sign , dytk )
60
+ print (user_url )
61
+ req = requests .get (user_url , headers = self .headers )
62
+ while req .status_code != 200 :
63
+ req = requests .get (user_url , headers = self .headers )
64
+ html = json .loads (req .text )
65
+ for each in html ['aweme_list' ]:
66
+ share_desc = each ['share_info' ]['share_desc' ]
67
+ if os .name == 'nt' :
68
+ for c in r'\/:*?"<>|' :
69
+ nickname = nickname .replace (c , '' ).strip ()
70
+ share_desc = share_desc .replace (c , '' ).strip ()
71
+ share_id = each ['aweme_id' ]
72
+ if share_desc in ['抖音-原创音乐短视频社区' , 'TikTok' ]:
73
+ video_names .append (share_id + '.mp4' )
74
+ else :
75
+ video_names .append (share_id + '-' + share_desc + '.mp4' )
76
+ share_urls .append (each ['share_info' ]['share_url' ])
77
+ video_urls .append (each ['video' ]['play_addr' ]['url_list' ][0 ])
78
+ max_cursor = html ['max_cursor' ]
79
+ has_more = html ['has_more' ]
82
80
83
81
return video_names , video_urls , share_urls , nickname
84
82
@@ -135,7 +133,7 @@ def run(self):
135
133
None
136
134
"""
137
135
self .hello ()
138
- user_id = input ('请输入ID(例如145651081 ):' )
136
+ user_id = input ('请输入UID(例如60388937600 ):' )
139
137
watermark_flag = int (input ('是否下载带水印的视频(0-否,1-是):' ))
140
138
video_names , video_urls , share_urls , nickname = self .get_video_urls (user_id )
141
139
if nickname not in os .listdir ():
0 commit comments