1. import os
    2. import re
    3. from queue import Queue
    4. from threading import Thread
    5. import requests
    6. class Demo(Thread):
    7. def __init__(self, queue):
    8. Thread.__init__(self)
    9. self.queue = queue
    10. self.headers = {
    11. "user-agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Mobile Safari/537.36"
    12. }
    13. def run(self):
    14. while True:
    15. video_info = self.queue.get()
    16. try:
    17. self.parse(video_info)
    18. finally:
    19. self.queue.task_done()
    20. def parse(self, video_info):
    21. file_name = re.sub(r"[/\\:*?\"<>|]", "_", video_info['desc'])
    22. if not file_name:
    23. file_name = video_info["aweme_id"]
    24. file_name = video_info["sort_name"] + " " + file_name
    25. if os.path.exists(file_name + ".mp4"):
    26. print("文件存在,{}.mp4".format(file_name))
    27. return
    28. video_url = video_info['video']['play_addr']['url_list'][0]
    29. with open(file_name + ".mp4", 'wb') as f:
    30. f.write(requests.get(url=video_url, headers=self.headers).content)
    31. print('下载成功: {}.mp4'.format(file_name))
    32. class DouYin:
    33. def __init__(self):
    34. self.share_url = input('粘贴分享链接:')
    35. # self.share_url = '在抖音,记录美好生活! https://v.douyin.com/ekkTsYw/'
    36. self.headers = {
    37. "user-agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Mobile Safari/537.36"
    38. }
    39. self.sort_num = 1
    40. self.video_list = []
    41. self.queue = Queue()
    42. # 解析粘贴内容里的url
    43. def parse_share_url(self):
    44. return re.findall('[a-z]+://[\S]+', self.share_url, re.I | re.M)[0]
    45. def get_sec_uid(self):
    46. url = self.parse_share_url()
    47. location = requests.get(url, headers=self.headers, allow_redirects=False).headers['location']
    48. return re.findall('sec_uid=(.*?)&', location)[0]
    49. # 创建用户名目录
    50. def init_save_dir(self, sec_uid):
    51. userinfo = requests.get(url='https://www.iesdouyin.com/web/api/v2/user/info/?sec_uid={}'.format(sec_uid), headers=self.headers).json()
    52. save_path = userinfo['user_info']['nickname']
    53. if not os.path.exists(save_path):
    54. os.mkdir(save_path)
    55. os.chdir(save_path) # 变更工作目录
    56. def get_video_list(self, sec_uid, max_cursor=0):
    57. url = "https://www.iesdouyin.com/web/api/v2/aweme/post/?sec_uid={}&count=21&max_cursor={}".format(sec_uid, max_cursor)
    58. # yield
    59. resp = requests.get(url, headers=self.headers)
    60. data = resp.json()
    61. if data["aweme_list"]:
    62. for video_info in data["aweme_list"]:
    63. self.video_list.append(video_info)
    64. print("下一页", url)
    65. self.get_video_list(sec_uid, data["max_cursor"])
    66. def run(self):
    67. sec_uid = self.get_sec_uid()
    68. self.init_save_dir(sec_uid)
    69. self.get_video_list(sec_uid)
    70. for x in range(10):
    71. worker = Demo(self.queue)
    72. worker.daemon = True
    73. worker.start()
    74. self.video_list.reverse()
    75. for video_info in self.video_list:
    76. video_info["sort_name"] = "[{}]".format(self.sort_num)
    77. self.sort_num += 1
    78. self.queue.put(video_info)
    79. self.queue.join()
    80. if __name__ == '__main__':
    81. DouYin().run()