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结合opencv实现人脸检测与跟踪
Jun 08 Python
python3 图片referer防盗链的实现方法
Mar 12 Python
python运行时强制刷新缓冲区的方法
Jan 14 Python
解决python字典对值(值为列表)赋值出现重复的问题
Jan 20 Python
Python使用微信itchat接口实现查看自己微信的信息功能详解
Aug 22 Python
详解python3中用HTMLTestRunner.py报ImportError: No module named 'StringIO'如何解决
Aug 27 Python
Python文件路径名的操作方法
Oct 30 Python
python 如何去除字符串头尾的多余符号
Nov 19 Python
Python imageio读取视频并进行编解码详解
Dec 10 Python
Python基于gevent实现高并发代码实例
May 15 Python
Python基于network模块制作电影人物关系图
Jun 19 Python
基于Python pyecharts实现多种图例代码解析
Aug 10 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
Win2003下APACHE+PHP5+MYSQL4+PHPMYADMIN 的简易安装配置
2006/11/18 PHP
php中使用preg_match_all匹配文章中的图片
2013/02/06 PHP
PHP函数getenv简介和使用实例
2014/05/12 PHP
thinkphp缓存技术详解
2014/12/09 PHP
Yii快速入门经典教程
2015/12/28 PHP
PHP错误机制知识汇总
2016/03/24 PHP
Laravel中Facade的加载过程与原理详解
2017/09/22 PHP
PHP在同一域名下两个不同的项目做独立登录机制详解
2017/09/22 PHP
表单(FORM)的一些实用效果代码
2007/03/25 Javascript
javascript实现div的拖动并调整大小类似qq空间个性编辑模块
2012/12/12 Javascript
浅谈 jQuery 事件源码定位问题
2014/06/18 Javascript
js的延迟执行问题分析
2014/06/23 Javascript
Javascript中实现trim()函数的两种方法
2015/02/04 Javascript
jQuery通过写入cookie实现更换网页背景的方法
2016/04/15 Javascript
详解原生JavaScript实现jQuery中AJAX处理的方法
2016/05/10 Javascript
14 个折磨人的 JavaScript 面试题
2016/08/08 Javascript
JS实现仿百度文库评分功能
2017/01/12 Javascript
js中创建对象的几种方式
2017/02/05 Javascript
javascript 操作cookies详解及实例
2017/02/22 Javascript
详解nodejs微信公众号开发——3.封装消息响应模块
2017/04/10 NodeJs
jQuery插件实现的日历功能示例【附源码下载】
2018/09/07 jQuery
Vue3.0数据响应式原理详解
2019/10/09 Javascript
mpvue 项目初始化及实现授权登录的实现方法
2020/07/20 Javascript
[00:37]DOTA2上海特级锦标赛 OG战队宣传片
2016/03/03 DOTA
[56:13]DOTA2-DPC中国联赛定级赛 LBZS vs Phoenix BO3第一场 1月10日
2021/03/11 DOTA
python实现进程间通信简单实例
2014/07/23 Python
解决python中无法自动补全代码的问题
2018/12/04 Python
python爬虫URL重试机制的实现方法(python2.7以及python3.5)
2018/12/18 Python
Python Pandas 如何shuffle(打乱)数据
2019/07/30 Python
Python定时发送天气预报邮件代码实例
2019/09/09 Python
迪梵英国官方网站:Darphin英国
2017/12/06 全球购物
意大利买卖二手奢侈品网站:LAMPOO
2020/06/03 全球购物
得到Class的三个过程是什么
2012/08/10 面试题
南京某软件公司的.net面试题
2015/11/30 面试题
社区优秀志愿者先进事迹
2014/05/09 职场文书
2014年宣传部工作总结
2014/11/12 职场文书