Python爬虫 批量爬取下载抖音视频代码实例


Posted in Python onAugust 16, 2019

这篇文章主要为大家详细介绍了python批量爬取下载抖音视频,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

Python爬虫 批量爬取下载抖音视频代码实例

项目源码展示:

'''
在学习过程中有什么不懂得可以加我的
python学习交流扣扣qun,934109170
群里有不错的学习教程、开发工具与电子书籍。
与你分享python企业当下人才需求及怎么从零基础学习好python,和学习什么内容。
'''
# -*- coding:utf-8 -*-
from contextlib import closing
import requests, json, re, os, sys, random
from ipaddress import ip_address
from subprocess import Popen, PIPE
import urllib
class DouYin(object):
 def __init__(self, width = 500, height = 300):
 """
 抖音App视频下载
 """
 rip = ip_address('0.0.0.0')
 while rip.is_private:
 rip = ip_address('.'.join(map(str, (random.randint(0, 255) for _ in range(4)))))
 self.headers = {
 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
 'accept-encoding': 'gzip, deflate, br',
 'accept-language': 'zh-CN,zh;q=0.9',
 'pragma': 'no-cache',
 'cache-control': 'no-cache',
 'upgrade-insecure-requests': '1',
 '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',
 'X-Real-IP': str(rip),
 'X-Forwarded-For': str(rip),
 }
 def get_video_urls(self, user_id, type_flag='f'):
 """
 获得视频播放地址
 Parameters:
 user_id:查询的用户UID
 Returns:
 video_names: 视频名字列表
 video_urls: 视频链接列表
 nickname: 用户昵称
 """
 video_names = []
 video_urls = []
 share_urls = []
 max_cursor = 0
 has_more = 1
 i = 0
 share_user_url = 'https://www.douyin.com/share/user/%s' % user_id
 share_user = requests.get(share_user_url, headers=self.headers)
 while share_user.status_code != 200:
 share_user = requests.get(share_user_url, headers=self.headers)
 _dytk_re = re.compile(r"dytk\s*:\s*'(.+)'")
 dytk = _dytk_re.search(share_user.text).group(1)
 _nickname_re = re.compile(r'<p class="nickname">(.+?)<\/p>')
 nickname = _nickname_re.search(share_user.text).group(1)
 urllib.request.urlretrieve('https://raw.githubusercontent.com/Jack-Cherish/python-spider/master/douyin/fuck-byted-acrawler.js', 'fuck-byted-acrawler.js')
 try:
 Popen(['node', '-v'], stdout=PIPE, stderr=PIPE).communicate()
 except (OSError, IOError) as err:
 print('请先安装 node.js: https://nodejs.org/')
 sys.exit()
 user_url_prefix = 'https://www.douyin.com/aweme/v1/aweme/favorite' if type_flag == 'f' else 'https://www.douyin.com/aweme/v1/aweme/post'
 print('解析视频链接中')
 while has_more != 0:
 process = Popen(['node', 'fuck-byted-acrawler.js', str(user_id)], stdout=PIPE, stderr=PIPE)
 _sign = process.communicate()[0].decode().strip('\n').strip('\r')
 user_url = user_url_prefix + '/?user_id=%s&max_cursor=%s&count=21&aid=1128&_signature=%s&dytk=%s' % (user_id, max_cursor, _sign, dytk)
 req = requests.get(user_url, headers=self.headers)
 while req.status_code != 200:
 req = requests.get(user_url, headers=self.headers)
 html = json.loads(req.text)
 try:
 while html['aweme_list'] == []:
  i = i + 1
  sys.stdout.write('已重新链接' + str(i) + '次 (若超过100次,请ctrl+c强制停止再重来)' + '\r')
  sys.stdout.flush()
  process = Popen(['node', 'fuck-byted-acrawler.js', str(user_id)], stdout=PIPE, stderr=PIPE)
  _sign = process.communicate()[0].decode().strip('\n').strip('\r')
  user_url = user_url_prefix + '/?user_id=%s&max_cursor=%s&count=21&aid=1128&_signature=%s&dytk=%s' % (user_id, max_cursor, _sign, dytk)
  req = requests.get(user_url, headers=self.headers)
  while req.status_code != 200:
  req = requests.get(user_url, headers=self.headers)
  html = json.loads(req.text)
 except:
 pass
 i = 0
 for each in html['aweme_list']:
 try:
  url = 'https://aweme.snssdk.com/aweme/v1/play/?video_id=%s&line=0&ratio=720p&media_type=4&vr_type=0&test_cdn=None&improve_bitrate=0'
  uri = each['video']['play_addr']['uri']
  video_url = url % uri
 except:
  continue
 share_desc = each['share_info']['share_desc']
 if os.name == 'nt':
  for c in r'\/:*?"<>|':
  nickname = nickname.replace(c, '').strip().strip('\.')
  share_desc = share_desc.replace(c, '').strip()
 share_id = each['aweme_id']
 if share_desc in ['抖音-原创音乐短视频社区', 'TikTok', '']:
  video_names.append(share_id + '.mp4')
 else:
  video_names.append(share_id + '-' + share_desc + '.mp4')
 share_urls.append(each['share_info']['share_url'])
 video_urls.append(video_url)
 max_cursor = html['max_cursor']
 has_more = html['has_more']
 return video_names, video_urls, share_urls, nickname
 def get_download_url(self, video_url, watermark_flag):
 """
 获得带水印的视频播放地址
 Parameters:
 video_url:带水印的视频播放地址
 Returns:
 download_url: 带水印的视频下载地址
 """
 # 带水印视频
 if watermark_flag == True:
 download_url = video_url.replace('/play/', '/playwm/')
 # 无水印视频
 else:
 download_url = video_url.replace('/playwm/', '/play/')
 return download_url
 def video_downloader(self, video_url, video_name, watermark_flag=False):
 """
 视频下载
 Parameters:
 video_url: 带水印的视频地址
 video_name: 视频名
 watermark_flag: 是否下载带水印的视频
 Returns:
 无
 """
 size = 0
 video_url = self.get_download_url(video_url, watermark_flag=watermark_flag)
 with closing(requests.get(video_url, headers=self.headers, stream=True)) as response:
 chunk_size = 1024
 content_size = int(response.headers['content-length'])
 if response.status_code == 200:
 sys.stdout.write(' [文件大小]:%0.2f MB\n' % (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 run(self):
 """
 运行函数
 Parameters:
 None
 Returns:
 None
 """
 self.hello()
 print('搜索api需要登录,暂时使用UID下载\n分享用户页面,用浏览器打开短链接,原始链接中/share/user/后的数字即是UID')
 user_id = input('请输入ID (例如95006183):')
 user_id = user_id if user_id else '95006183'
 watermark_flag = input('是否下载带水印的视频 (0-否(默认), 1-是):')
 watermark_flag = watermark_flag if watermark_flag!='' else '0'
 watermark_flag = bool(int(watermark_flag))
 type_flag = input('f-收藏的(默认), p-上传的:')
 type_flag = type_flag if type_flag!='' else 'f'
 save_dir = input('保存路径 (例如"E:/Download/", 默认"./Download/"):')
 save_dir = save_dir if save_dir else "./Download/"
 video_names, video_urls, share_urls, nickname = self.get_video_urls(user_id, type_flag)
 nickname_dir = os.path.join(save_dir, nickname)
 if not os.path.exists(save_dir):
 os.makedirs(save_dir)
 if nickname not in os.listdir(save_dir):
 os.mkdir(nickname_dir)
 if type_flag == 'f':
 if 'favorite' not in os.listdir(nickname_dir):
 os.mkdir(os.path.join(nickname_dir, 'favorite'))
 print('视频下载中:共有%d个作品!\n' % len(video_urls))
 for num in range(len(video_urls)):
 print(' 解析第%d个视频链接 [%s] 中,请稍后!\n' % (num + 1, share_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]
 video_path = os.path.join(nickname_dir, video_name) if type_flag!='f' else os.path.join(nickname_dir, 'favorite', video_name)
 if os.path.isfile(video_path):
 print('视频已存在')
 else:
 self.video_downloader(video_urls[num], video_path, watermark_flag)
 print('\n')
 print('下载完成!')
 def hello(self):
 """
 打印欢迎界面
 Parameters:
 None
 Returns:
 None
 """
 print('*' * 100)
 print('\t\t\t\t抖音App视频下载小助手')
 print('\t\t作者:Jack Cui、steven7851')
 print('*' * 100)
if __name__ == '__main__':
 douyin = DouYin()
 douyin.run()

运行结果:

Python爬虫 批量爬取下载抖音视频代码实例

爬取结果截图

Python爬虫 批量爬取下载抖音视频代码实例

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
在Python的gevent框架下执行异步的Solr查询的教程
Apr 16 Python
Python的面向对象编程方式学习笔记
Jul 12 Python
Python 12306抢火车票脚本 Python京东抢手机脚本
Feb 06 Python
Python OpenCV对本地视频文件进行分帧保存的实例
Jan 08 Python
使用python画社交网络图实例代码
Jul 10 Python
python+openCV调用摄像头拍摄和处理图片的实现
Aug 06 Python
OpenCV+face++实现实时人脸识别解锁功能
Aug 28 Python
selenium 多窗口切换的实现(windows)
Jan 18 Python
python字符串替换re.sub()实例解析
Feb 09 Python
Windows下Anaconda安装、换源与更新的方法
Apr 17 Python
Python闭包与装饰器原理及实例解析
Apr 30 Python
python的setattr函数实例用法
Dec 16 Python
django 使用 PIL 压缩图片的例子
Aug 16 #Python
详解PyTorch手写数字识别(MNIST数据集)
Aug 16 #Python
Python 等分切分数据及规则命名的实例代码
Aug 16 #Python
Python 分发包中添加额外文件的方法
Aug 16 #Python
解决Djang2.0.1中的reverse导入失败的问题
Aug 16 #Python
基于django传递数据到后端的例子
Aug 16 #Python
Django 拆分model和view的实现方法
Aug 16 #Python
You might like
php模拟socket一次连接,多次发送数据的实现代码
2011/07/26 PHP
简单的php写入数据库类代码分享
2011/07/26 PHP
PHP服务器页面间跳转实现方法
2012/08/02 PHP
PC端微信扫码支付成功之后自动跳转php版代码
2017/07/07 PHP
PHP上传图片到数据库并显示的实例代码
2019/12/20 PHP
PHPStorm2020.1永久激活及下载更新至2020(推荐)
2020/09/25 PHP
通过jquery的$.getJSON做一个跨域ajax请求试验
2011/05/03 Javascript
推荐40个非常优秀的jQuery插件和教程【系列三】
2011/11/09 Javascript
javascript 基础篇2 数据类型,语句,函数
2012/03/14 Javascript
js 判断上传文件大小及格式代码
2013/11/13 Javascript
node.js抓取并分析网页内容有无特殊内容的js文件
2015/11/17 Javascript
Javascript的表单验证-提交表单
2016/03/18 Javascript
基于js实现checkbox批量选中操作
2016/11/22 Javascript
Javascript中的prototype与继承
2017/02/06 Javascript
node.js利用redis数据库缓存数据的方法
2017/03/01 Javascript
Ajax高级笔记 JavaScript高级程序设计笔记
2017/06/22 Javascript
vue+vuex+axios+echarts画一个动态更新的中国地图的方法
2017/12/19 Javascript
Vue.directive 自定义指令的问题小结
2018/03/04 Javascript
关于微信公众号开发无法支付的问题解决
2018/12/28 Javascript
微信小程序常用的3种提示弹窗实现详解
2019/09/19 Javascript
Vue +WebSocket + WaveSurferJS 实现H5聊天对话交互的实例
2020/11/18 Vue.js
[58:32]EG vs Liquid 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
复习Python中的字符串知识点
2015/04/14 Python
python分割列表(list)的方法示例
2017/05/07 Python
flask框架使用orm连接数据库的方法示例
2018/07/16 Python
Pytorch 计算误判率,计算准确率,计算召回率的例子
2020/01/18 Python
使用Python求解带约束的最优化问题详解
2020/02/11 Python
Python 如何调试程序崩溃错误
2020/08/03 Python
python将YUV420P文件转PNG图片格式的两种方法
2021/01/22 Python
详解matplotlib绘图样式(style)初探
2021/02/03 Python
CSS3绘制有活力的链接下划线
2016/07/14 HTML / CSS
Tretorn美国官网:瑞典外套和鞋类品牌,抵御风雨
2018/07/19 全球购物
C#软件工程师英语面试题
2015/06/07 面试题
教师党员自我剖析材料
2014/09/29 职场文书
eval(cmd)与eval($cmd)的区别与联系
2021/07/07 PHP
十大冰系宝可梦排名,颜值最高的阿罗拉九尾,第三使用率第一
2022/03/18 日漫