基于Python实现全自动下载抖音视频


Posted in Python onNovember 06, 2020

很多人喜欢玩抖音,我也喜欢看抖音小姐姐,可拿着手机一个个找视频太费劲。作为一个程序员,如何能在电脑前一边编程一边轻松地看抖音小姐姐呢?

下面利用Python,简单的三个步骤就可以将你喜欢的抖音小姐姐的视频自动下载下来了。

Charles

Charles是一个App抓包工具,与Filddler的功能相似,利用它可以得到App运行过程中发生的所有网络请求和响应内容。

在电脑端下载安装完Charles后,需要配置证书,最后开启SSL监听。

手机端则是需要与电脑在同一网络下,比如都连接家里的Wi-Fi,然后在手机的Wi-Fi高级选项里使用Charles代理,输入电脑的IP地址,端口8888,最后为证书命名。

连好以后,手机打开抖音App,随着操作App的动作,可以获取到视频的请求信息。

基于Python实现全自动下载抖音视频

通过多次实验,发现链接的后面是会不停的改变,只有链接的前头始终不变,即「http://v1-dy」「http://v6-dy」「http://v9-dy」不变。

所以在写脚本的时候,可以用这些信息做为链接开头。

MitmProxy

基于Python实现全自动下载抖音视频

利用MitmProxy中的mitmdump组件,对接Python脚本,用Python实现监听后的处理。

这里我只是利用脚本获取链接,并没有直接利用脚本下载视频。

因为我是在mitmdump.exe文件所在的文件夹运行脚本,脚本里导入不了requests模块。

不想配置环境变量了,所以只获取链接。

利用链接再去下载视频,视频链接需要去重,因为可能会有重复的。

Python脚本如下:

def response(flow):
  urls = ['http://v1-dy', 'http://v3-dy', 'http://v6-dy', 'http://v9-dy']
  # 对url进行筛选,只选取视频的url
  for url in urls:
    if url in flow.request.url:
      print('\n\n抖音视频\n\n')
      with open('douyin.csv', 'a+', encoding='utf-8-sig') as f:
        f.write(flow.request.url + '\n')

配置抖音的Appium参数:

基于Python实现全自动下载抖音视频

点击蓝色按钮,手机自动启动抖音App。接着操作手机,然后点击Appium的刷新键,获取元素定位代码。

通过本次的实践发现Appium有时并不能很好的获取元素的定位,针对找不到的元素,我直接对手机屏幕位置进行点击。

由于大家手机屏幕大小不同,这个参数肯定是会变化的,所以存在弊端,无法通用。

左右滑动切换图片

基于Python实现全自动下载抖音视频

基于Python实现全自动下载抖音视频

基于Python实现全自动下载抖音视频

大致操作如上图。UP主的主页图漏了,请自行脑补,Python代码如下:

import time
import random
from appium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from appium.webdriver.common.touch_action import TouchAction
from selenium.webdriver.support import expected_conditions as EC


def main():
  # 设置驱动配置
  server = 'http://localhost:4723/wd/hub'
  desired_caps = {
    'platformName': 'Android',
    'deviceName': 'STF_AL00',
    'appPackage': 'com.ss.android.ugc.aweme',
    'appActivity': '.main.MainActivity',
    # 关闭手机软键盘
    'unicodeKeyboard': True,
    'resetKeyboard': True
  }
  driver = webdriver.Remote(server, desired_caps)
  wait = WebDriverWait(driver, 60)
  # 同意用户隐私协议,点击
  button_1 = wait.until(EC.presence_of_element_located((By.ID, 'com.ss.android.ugc.aweme:id/q6')))
  button_1.click()
  # 禁止电话权限,点击
  button_2 = wait.until(EC.presence_of_element_located((By.ID, 'com.android.packageinstaller:id/permission_deny_button')))
  button_2.click()
  # 禁止位置权限,点击
  button_3 = wait.until(EC.presence_of_element_located((By.ID, 'com.android.packageinstaller:id/permission_deny_button')))
  button_3.click()
  time.sleep(2)
  # 向上滑动,进入抖音视频播放页面
  TouchAction(driver).press(x=515, y=1200).move_to(x=515, y=1000).release().perform()
  # 这里需要设置一个较长时间的延迟,因为抖音有引导操作和提示,需等待片刻
  time.sleep(20)
  # 点击抖音"喜欢"处,以此进入登录界面
  TouchAction(driver).press(x=950, y=800).release().perform()
  # 点击密码登录
  button_4 = wait.until(EC.presence_of_element_located((By.ID, 'com.ss.android.ugc.aweme:id/afg')))
  button_4.click()
  # 输入账号
  button_5 = wait.until(EC.presence_of_element_located((By.ID, 'com.ss.android.ugc.aweme:id/ab_')))
  button_5.send_keys('你的账号')
  # 输入密码
  button_6 = wait.until(EC.presence_of_element_located((By.ID, 'com.ss.android.ugc.aweme:id/aes')))
  button_6.send_keys('你的密码')
  time.sleep(2)
  # 因为会跳出软键盘,会遮挡登录按钮,需点击软键盘取消
  TouchAction(driver).press(x=980, y=1850).release().perform()
  time.sleep(2)
  # 点击登录按钮
  button_7 = wait.until(EC.presence_of_element_located((By.ID, 'com.ss.android.ugc.aweme:id/abb')))
  button_7.click()
  time.sleep(2)
  # 登录成功,进入抖音视频界面,点击下方标题栏 "我"
  TouchAction(driver).press(x=990, y=1850).release().perform()
  # 进入个人主页,点击关注处
  button_8 = wait.until(EC.presence_of_element_located((By.ID, 'com.ss.android.ugc.aweme:id/a_7')))
  button_8.click()
  # 进入关注栏,点击第二个关注
  button_9 = wait.until(EC.presence_of_element_located((By.XPATH, '  /hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.view.ViewGroup/android.widget.LinearLayout/android.support.v7.widget.RecyclerView/android.widget.RelativeLayout[2]/android.widget.RelativeLayout[1]')))
  button_9.click()
  # 进入UP主主页,点击第一个视频
  button_10 = wait.until(EC.presence_of_element_located((By.ID, 'com.ss.android.ugc.aweme:id/aqm')))
  button_10.click()
  # 不断下滑页面,直到底部
  while True:
    TouchAction(driver).press(x=515, y=1247).move_to(x=515, y=1026).release().perform()
    time.sleep(float(random.randint(5, 10)))


if __name__ == '__main__':
  main()

下载视频代码,需要对视频链接去重:

import pandas as pd
import requests
import os

num = 0
dom = []
folder_path = "F:/video/"
os.makedirs(folder_path)
df = pd.read_csv('douyin.csv', header=None, names=["url"])

# 对链接去重及去除刚进入抖音获取的视频链接
for i in df['url'][2:]:
  if i not in dom:
    dom.append(i)
# 下载视频
for j in dom:
  url = j
  num += 1
  response = requests.get(url, stream=True)
  filename = str(num) + '.mp4'
  with open('F:\\video\\' + filename, 'ab+') as f:
    f.write(response.content)
    f.flush()
    print(filename + '下载完成')

最后成功获取小姐姐们的全部视频:

基于Python实现全自动下载抖音视频

我打算将视频里喜欢的妹子全剪辑出来,做一个「最美瞬间」系列的视频,分享给大家!

源码地址:

https://github.com/Tobby-star/douyin

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

Python 相关文章推荐
Python中Collection的使用小技巧
Aug 18 Python
Python类方法__init__和__del__构造、析构过程分析
Mar 06 Python
python提取内容关键词的方法
Mar 16 Python
在Python中操作字符串之startswith()方法的使用
May 20 Python
浅析Python的Django框架中的Memcached
Jul 23 Python
Python实现的递归神经网络简单示例
Aug 11 Python
EM算法的python实现的方法步骤
Jan 02 Python
Python日期时间模块datetime详解与Python 日期时间的比较,计算实例代码
Sep 14 Python
Python操作redis实例小结【String、Hash、List、Set等】
May 16 Python
在OpenCV里实现条码区域识别的方法示例
Dec 04 Python
Django与pyecharts结合的实例代码
May 13 Python
python如何从键盘获取输入实例
Jun 18 Python
Python3读写ini配置文件的示例
Nov 06 #Python
Python Serial串口基本操作(收发数据)
Nov 06 #Python
python基于exchange函数发送邮件过程详解
Nov 06 #Python
Python Unittest原理及基本使用方法
Nov 06 #Python
python中的yield from语法快速学习
Nov 06 #Python
Python通过字典映射函数实现switch
Nov 06 #Python
Python使用grequests并发发送请求的示例
Nov 05 #Python
You might like
php设计模式小结
2013/02/15 PHP
小谈php正则提取图片地址
2014/03/27 PHP
phpMyAdmin自动登录和取消自动登录的配置方法
2014/05/12 PHP
php把大写命名转换成下划线分割命名
2015/04/27 PHP
php设置页面超时时间解决方法
2015/09/22 PHP
PHP substr()函数参数解释及用法讲解
2017/11/23 PHP
简略说明Javascript中的= =(等于)与= = =(全等于)区别
2013/04/16 Javascript
js实现动画特效的文字链接鼠标悬停提示的方法
2015/03/02 Javascript
javascript原型模式用法实例详解
2015/06/04 Javascript
JavaScript学习笔记之数组的增、删、改、查
2016/03/23 Javascript
Angularjs 动态改变title标题(兼容ios)
2016/12/29 Javascript
jQuery使用siblings获取某元素所有同辈(兄弟姐妹)元素用法示例
2017/01/30 Javascript
Angularjs自定义指令实现三级联动 选择地理位置
2017/02/13 Javascript
详解在AngularJS的controller外部直接获取$scope
2017/06/02 Javascript
angular使用bootstrap方法手动启动的实例代码
2017/07/18 Javascript
Vue.js实现输入框绑定的实例代码
2017/08/24 Javascript
vue学习教程之带你一步步详细解析vue-cli
2017/12/26 Javascript
vue-property-decorator用法详解
2019/12/12 Javascript
微信小程序实现天气预报功能(附源码)
2020/12/10 Javascript
[01:06]DOTA2隆重推出2016冬季勇士令状 内含上海特级锦标赛互动指南
2016/02/17 DOTA
python登录QQ邮箱发信的实现代码
2013/02/10 Python
在Linux下使用Python的matplotlib绘制数据图的教程
2015/06/11 Python
Python抓取框架 Scrapy的架构
2016/08/12 Python
python pyheatmap包绘制热力图
2018/11/09 Python
python中enumerate() 与zip()函数的使用比较实例分析
2019/09/03 Python
python给指定csv表格中的联系人群发邮件(带附件的邮件)
2019/12/31 Python
CSS3中Animation动画属性用法详解
2016/07/04 HTML / CSS
使用placeholder属性设置input文本框的提示信息
2020/02/19 HTML / CSS
2019年.net常见面试问题
2012/02/12 面试题
经济信息管理专业大学生求职信
2013/09/27 职场文书
毕业生的自我鉴定该怎么写
2013/12/02 职场文书
心理健康课教学反思
2014/02/13 职场文书
行政文员实习自我鉴定范文
2014/09/14 职场文书
个人党性锻炼总结
2015/03/05 职场文书
html form表单基础入门案例讲解
2021/07/15 HTML / CSS
Nginx代理Redis哨兵主从配置的实现
2022/07/15 Servers