zoukankan      html  css  js  c++  java
  • from appium import webdriver 使用python爬虫,批量爬取抖音app视频(requests+Fiddler+appium)

    使用python爬虫,批量爬取抖音app视频(requests+Fiddler+appium) - 北平吴彦祖 - 博客园 https://www.cnblogs.com/stevenshushu/p/9635097.html

    抖音很火,楼主使用python随机爬取抖音视频,并且无水印下载,人家都说天下没有爬不到的数据,so,楼主决定试试水,纯属技术爱好,分享给大家。。

    1.楼主首先使用Fiddler4来抓取手机抖音app这个包,具体配置的操作,网上有很多教程供大家参考。

    上面得出抖音的视频的url,这些url均能在网页中打开,楼主数了数,这些url的前缀有些不同,一共有这4种类型:

    v1-dy.ixigua.com

    v3-dy.ixigua.com

    v6-dy.ixigua.com

    v9-dy.ixigua.com

     楼主查看这四种类型得知,v6-dy.ixigua.com 这个前缀后面的参数其中有一个是Expires(中文含义过期的意思)

    Expires=1536737310,这个是时间戳,标记的是过期的时间如下图所示,过了15:28分30秒,则表示url不能使用,楼主算了一下,url有效期是一个小时。

    看到这些url,楼主不能手动一个一个粘贴,so楼主需要在+Fiddler4中(在Fiddler4使用script代码网上有大量详细教程)使用如下代码,自动保存到一个txt文档中。

    复制代码
            //保存到本地添加开始
            
            //这是抖音的地址||"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:" + "
    " + oSession.oRequest.headers);
                //file.writeLine("Request-body:" + oSession.GetRequestBodyAsString());
                //file.writeLine("
    ");
                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())#去掉
     strip去掉头尾默认空格或换行符
        # print(datalist)
        data_dict={}
        for data in datalist_blank:
            #print(type(data),data,'
    ')
            #print(data.split('/'),'
    ',data.split('/').index('m'),'
    ')
            #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("
    [%s%s] %d % %" % ('█' * done, ' ' * (50 - done), 100 * temp_size / total_size)+" 下载信息:"+pathinfo + "下载完成啦啦啦啦啦")
                            sys.stdout.flush()#刷新缓存
                    #############下载进度条部分end###############
                    print('
    ')#每一条打印在屏幕上换行输出
    
    
    if __name__ == '__main__':
        responsedouyin()
    复制代码

    运行代码,效果图如下

    视频最终保存到文件夹中

    github地址:https://github.com/Stevenguaishushu/douyin

  • 相关阅读:
    BadgeView使用
    设计模式(一)单例模式的七种写法
    Android 之使用LocalBroadcastManager解决BroadcastReceiver安全问题
    AsyncTask源码分析
    Android微信支付—注意事项
    Android微信支付SDK开发
    Android支付宝SDK开发笔记
    onInterceptTouchEvent与onTouchEvent默认返回值
    线程间的通信方式3--Handler
    Android应用程序启动过程(二)分析
  • 原文地址:https://www.cnblogs.com/rsapaper/p/10761331.html
Copyright © 2011-2022 走看看