抖音很火,楼主使用python随机爬取抖音视频,而且无水印下载,人家都说天下没有爬不到的数据,so,楼主决定试试水,纯属技术爱好,分享给你们。。python
1.楼主首先使用Fiddler4来抓取手机抖音app这个包,具体配置的操做,网上有不少教程供你们参考。android
上面得出抖音的视频的url,这些url均能在网页中打开,楼主数了数,这些url的前缀有些不一样,一共有这4种类型:git
v1-dy.ixigua.comgithub
v3-dy.ixigua.comweb
v6-dy.ixigua.com缓存
v9-dy.ixigua.comapp
楼主查看这四种类型得知,v6-dy.ixigua.com 这个前缀后面的参数其中有一个是Expires(中文含义过时的意思)ide
Expires=1536737310,这个是时间戳,标记的是过时的时间以下图所示,过了15:28分30秒,则表示url不能使用,楼主算了一下,url有效期是一个小时。函数
看到这些url,楼主不能手动一个一个粘贴,so楼主须要在+Fiddler4中(在Fiddler4使用script代码网上有大量详细教程)使用以下代码,自动保存到一个txt文档中。url
//保存到本地添加开始
//这是抖音的地址||"v1-dy.ixigua.com"||"v3-dy.ixigua.com"||"v6-dy.ixigua.com"||"v9-dy.ixigua.com"||
if (oSession.fullUrl.Contains("v1-dy.ixigua.com")||
oSession.fullUrl.Contains("v3-dy.ixigua.com")||
oSession.fullUrl.Contains("v6-dy.ixigua.com")||
oSession.fullUrl.Contains("v9-dy.ixigua.com")){
var fso;
var file;
fso = new ActiveXObject("Scripting.FileSystemObject");
//文件保存路径,可自定义
file = fso.OpenTextFile("H:\\Request.txt",8 ,true);
//file.writeLine("Request-url:" + oSession.url);
file.writeLine("http://"+oSession.url)
//file.writeLine("Request-host:" + oSession.host);
//file.writeLine("Request-header:" + "\n" + oSession.oRequest.headers);
//file.writeLine("Request-body:" + oSession.GetRequestBodyAsString());
//file.writeLine("\n");
file.close();
}
//保存到本地添加结束
把上边的代码插入到以下图所示的地方便可。
2.上面的url是楼主手动点击一个个刷新抖音app出现的,so楼主使用appium来自动刷新抖音app,自动得到url,自动保存到txt文档中。
首先须要在appium中获得抖音这个app包的一些用的信息,以下图所示
楼主使用的是红米手机,至于appium怎么安装配置,你们可参考网上相关教程,appium客户端链接上手机(须要数据线链接)后,在控制台打印出log日志文件,在日志文件中找到这四个参数便可,而后保存
到appium客户端中便可,就能在appium客户端中操做抖音app。
{
"platformName": "Android",
"deviceName": "Redmi Note5",
"appPackage": "com.ss.android.ugc.aweme",
"appActivity": ".main.MainActivity"
}
appPackage这一项com.ss.android.ugc.aweme 则表示抖音短视频。
楼主使用以下代码来实现无限刷新抖音app,前提是须要手机连着数据线连在电脑上而且开启appium客户端的服务和打开Fiddler4抓包(配置好环境手机)。
from appium import webdriver from time import sleep ##如下代码能够操控手机app class Action(): def __init__(self): # 初始化配置,设置Desired Capabilities参数 self.desired_caps = { "platformName": "Android", "deviceName": "Mi_Note_3", "appPackage": "com.ss.android.ugc.aweme", "appActivity": ".main.MainActivity" } # 指定Appium Server self.server = 'http://localhost:4723/wd/hub' # 新建一个Session self.driver = webdriver.Remote(self.server, self.desired_caps) # 设置滑动初始坐标和滑动距离 self.start_x = 500 self.start_y = 1500 self.distance = 1300 def comments(self): sleep(3) # app开启以后点击一次屏幕,确保页面的展现 self.driver.tap([(500, 1200)], 500) def scroll(self): # 无限滑动 while True: # 模拟滑动 self.driver.swipe(self.start_x, self.start_y, self.start_x, self.start_y - self.distance) # 设置延时等待 sleep(5) def main(self): self.comments() self.scroll() if __name__ == '__main__': action = Action() action.main()
楼主运行次代码就能在Fiddler4中获得无限量的url。
3.楼主拿到url后,会发现有些url会重复,so楼主加入了去重的功能,为了好看楼主也加入了进度条花里花哨的功能,运行代码最终会下载下来。
# _*_ coding: utf-8 _*_ import requests import sys headers = {"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36" } ##去重方法 def distinct_data(): ##读取txt中文档的url列表 datalist_blank=[] pathtxt='H:/Request.txt' with open(pathtxt) as f: f_data_list=f.readlines()#d获得的是一个list类型 for a in f_data_list: datalist_blank.append(a.strip())#去掉\n strip去掉头尾默认空格或换行符 # print(datalist) data_dict={} for data in datalist_blank: #print(type(data),data,'\n') #print(data.split('/'),'\n',data.split('/').index('m'),'\n') #url中以/为切分,在以m为切分 ##把m后面的值放进字典key的位置,利用字典特性去重 if int(data.split('/').index('m'))==4 :#此处为v6开头的url #print(data,44,data.split('/')[5]) data_key1=data.split("/")[5] data_dict[data_key1]=data elif int(data.split('/').index('m'))==6: #此处为v1或者v3或者v9开头的url #print(data,66,data.split('/')[7],type(data.split('/')[7])) data_key2=data.split("/")[7] data_dict[data_key2] =data #print(len(data_dict),data_dict) data_new=[] for x,y in data_dict.items(): data_new.append(y) return data_new def responsedouyin(): data_url=distinct_data() # 使用request获取视频url的内容 # stream=True做用是推迟下载响应体直到访问Response.content属性 # 将视频写入文件夹 num = 1 for url in data_url: res = requests.get(url,stream=True,headers=headers) #res = requests.get(url=url, stream=True, headers=headers) #定义视频存放的路径 pathinfo = 'H:/douyin-video/%d.mp4' % num #%d 用于整数输出 %s用于字符串输出 # 实现下载进度条显示,这一步须要获得总视频大小 total_size = int(res.headers['Content-Length']) #print('这是视频的总大小:',total_size) #设置流的起始值为0 temp_size = 0 if res.status_code == 200: with open(pathinfo, 'wb') as file: #file.write(res.content) #print(pathinfo + '下载完成啦啦啦啦啦') num += 1 #当流下载时,下面是优先推荐的获取内容方式,iter_content()函数就是获得文件的内容,指定chunk_size=1024,大小能够本身设置哟,设置的意思就是下载一点流写一点流到磁盘中 for chunk in res.iter_content(chunk_size=1024): if chunk: temp_size += len(chunk) file.write(chunk) file.flush() #刷新缓存 #############下载进度条部分start############### done = int(50 * temp_size / total_size) #print('百分比:',done) sys.stdout.write("\r[%s%s] %d % %" % ('█' * done, ' ' * (50 - done), 100 * temp_size / total_size)+" 下载信息:"+pathinfo + "下载完成啦啦啦啦啦") sys.stdout.flush()#刷新缓存 #############下载进度条部分end############### print('\n')#每一条打印在屏幕上换行输出 if __name__ == '__main__': responsedouyin()
运行代码,效果图以下
视频最终保存到文件夹中
github地址:https://github.com/Stevenguaishushu/douyin