基于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实现获取网站PR及百度权重
Jan 21 Python
Python实现比较两个文件夹中代码变化的方法
Jul 10 Python
Python的collections模块中的OrderedDict有序字典
Jul 07 Python
Python标准模块--ContextManager上下文管理器的具体用法
Nov 27 Python
Python+tkinter使用40行代码实现计算器功能
Jan 30 Python
Python实现基于TCP UDP协议的IPv4 IPv6模式客户端和服务端功能示例
Mar 22 Python
完美解决Python matplotlib绘图时汉字显示不正常的问题
Jan 29 Python
python实现AES加密和解密
Mar 27 Python
Window版下在Jupyter中编写TensorFlow的环境搭建
Apr 10 Python
pandas中的ExcelWriter和ExcelFile的实现方法
Apr 24 Python
MxNet预训练模型到Pytorch模型的转换方式
May 25 Python
详解Python中的路径问题
Sep 02 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
肝肠寸断了解下!盘点史上最伤心的十大动漫
2020/03/04 日漫
PHP遍历数组的几种方法
2012/03/22 PHP
php中动态修改ini配置
2014/10/14 PHP
PHP中set error handler函数用法小结
2015/11/11 PHP
thinkPHP模板算术运算相关函数用法分析
2016/07/12 PHP
浅谈socket同步和异步、阻塞和非阻塞、I/O模型
2016/12/15 PHP
利用PHP扩展Xhprof分析项目性能实践教程
2018/09/05 PHP
laravel ORM关联关系中的 with和whereHas用法
2019/10/16 PHP
laravel 解决Eloquent ORM的save方法无法插入数据的问题
2019/10/21 PHP
jValidate 基于jQuery的表单验证插件
2009/12/12 Javascript
Dom 学习总结以及实例的使用介绍
2013/04/24 Javascript
将json对象转换为字符串的方法
2014/02/20 Javascript
Javascript中Array用法实例分析
2015/06/13 Javascript
javascript生成不重复的随机数
2015/07/17 Javascript
详解Vue 非父子组件通信方法(非Vuex)
2017/05/24 Javascript
获取layer.open弹出层的返回值方法
2018/08/20 Javascript
JS获取并处理php数组的方法实例分析
2018/09/04 Javascript
基于vue v-for 多层循环嵌套获取行数的方法
2018/09/26 Javascript
Vue多组件仓库开发与发布详解
2019/02/28 Javascript
js HTML DOM EventListener功能与用法实例分析
2020/04/27 Javascript
微信小程序中使用 async/await的方法实例分析
2020/05/06 Javascript
[01:05]DOTA2完美大师赛趣味视频之选手教你打职业
2017/11/23 DOTA
使用python编写批量卸载手机中安装的android应用脚本
2014/07/21 Python
python实现用户答题功能
2018/01/17 Python
Python列表推导式、字典推导式与集合推导式用法实例分析
2018/02/07 Python
Python打印特殊符号及对应编码解析
2020/05/07 Python
Python学习之路之pycharm的第一个项目搭建过程
2020/06/18 Python
Python建造者模式案例运行原理解析
2020/06/29 Python
python 利用zmail库发送邮件
2020/09/11 Python
HTML5 HTMLCollection和NodeList的区别详解
2020/04/29 HTML / CSS
Omio波兰:全欧洲低价大巴、火车和航班搜索和比价
2018/02/16 全球购物
企业仓管员岗位职责
2014/06/15 职场文书
2014财产信托协议书范本
2014/11/18 职场文书
保研专家推荐信范文
2015/03/25 职场文书
Windows10下安装MySQL8
2021/04/06 MySQL
解决MySQL添加新用户-ERROR 1045 (28000)的问题
2022/03/03 MySQL