zoukankan      html  css  js  c++  java
  • 《自拍教程54》Python_批量下载1000个apk(附练手素材)

    之前我们做Android手机测试的时候,
    市场部希望我们测试部进行Top 1000 app(排名前1000的app)的兼容性测试,
    以确保我们的手机是可以安装并正常运行这么多好用的app,
    且市场部提供了某应用市场上的top 1000 的apk下载地址。

    如何实现快速批量地下载apk文件呢?


    准备阶段
    1. wget命令,requests模块,urllib模块等都可以进行文件的下载
    2. 以上excel里的的url分明是需要进行二次重定向的,因为其不是一个.apk结尾的链接,我们需要进行解析后再进行重定向。
    3. wget是不支持这类解析的,所以不能采用,wget由于是命令,比较局限,无法进行二次编程,所以我们还是采用requests模块来实现下载。
    4. 重点是如何实现快速下载,需要运用多线程技术。
    5. 多线程一般用Queen队列, 队列先进先出,如果队列里还有数据,则一直按指定的线程数(比如10个线程)进行run。

    Python批处理脚本形式—单线程的写法

    记住批处理脚本的精髓:批量顺序执行语句,
    由于批处理脚本形式只能实现单个apk的下载任务,我们使用requests模块实现下载。

    # coding=utf-8
    
    import os
    import requests
    import openpyxl
    
    curdir = os.getcwd() # 获取当前路径current work directory
    header = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1 WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36'}
    
    # 创建文件夹用于存放已经下载的apk
    if not os.path.exists("downloaded_apk"):
        os.system("mkdir downloaded_apk")
    
    # 逐行读取excel里的下载地址url
    excel = openpyxl.load_workbook('Top_1000_app.xlsx')  # 读取excel里边的内容
    table = excel.active
    rows = table.max_row
    for r in range(2, rows + 1):  # 跟excel的第一行标题行无关,从第二行文字内容开始
        apk_name = table.cell(row=r, column=2).value  # 获取app名字(中文)
        apk_url = table.cell(row=r, column=3).value  # 获取下载地址
        save_path = os.path.join(curdir, "downloaded_apk", "%s.apk" % apk_name)
        if not os.path.exists(save_path):  # 避免二次下载
            print("Downloading the %sth apk and will save to %s" % (r, save_path))
            try:
                r = requests.get(apk_url, headers=header, allow_redirects=True, timeout=720)  # 发起requests下载请求
                status_code = r.status_code
                if (status_code == 200 or status_code == 206):
                    with open(save_path, "wb") as hf:
                        hf.write(r.content)
            except:
                print("Error, can not download %s.apk" % apk_name)
        else:
            print("%s downloaded already!" % save_path)
    
    os.system("pause")
    

    Python面向对象类形式—多线程下载的写法

    多线程相对来说,理解上会较难一些些,
    一般是将任务放到Queue队列里去,先进先出,
    然后只要队列不是空队列,就从队列里边取任务(q_job),并有10个线程同时进行。

    #coding=utf-8
    
    import os
    import queue
    import threading
    import requests
    import openpyxl
    
    curdir = os.getcwd()  #获取当前路径current work directory
    header = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1 WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36'}
    
    # 创建文件夹
    if not os.path.exists("downloaded_apk"):
        os.system("mkdir downloaded_apk")
    
    
    def download_single_apk(apk_url_str):
        '''下载单个apk文件'''
        apk_name, apk_url = apk_url_str.split(";")
        # print(apk_url)
        save_path = os.path.join(curdir, "downloaded_apk", "%s.apk" % apk_name)
        if not os.path.exists(save_path):  # 避免二次下载
            print("Downloading  %s" % (save_path))
            try:
                r = requests.get(apk_url, headers=header, allow_redirects=True, timeout=720)  # 发起requests下载请求
                status_code = r.status_code
                if (status_code == 200 or status_code == 206):
                    with open(save_path, "wb") as hf:
                        hf.write(r.content)
            except:
                print("Error, can not download %s.apk" % apk_name)
        else:
            print("%s downloaded already!" % save_path)
    
    
    ###批量下载的线程
    class DownLoadThread(threading.Thread):
        def __init__(self, q_job):
            self._q_job = q_job
            threading.Thread.__init__(self)
    
        def run(self):
            while True:
                if self._q_job.qsize() > 0:
                    download_single_apk(self._q_job.get())  # 这是10个线程都运行这个下载函数
                else:
                    break
    
    
    if __name__ == '__main__':
        # 初始化一个队列
        q = queue.Queue(0)
        
        # 逐行读取excel里的url
        excel = openpyxl.load_workbook('Top_1000_app.xlsx')  # 读取excel里边的内容
        table = excel.active
        rows = table.max_row
        for r in range(2, rows + 1):  # 跟excel的第一行标题行无关,从第二行文字内容开始做替换工作
            apk_name = table.cell(row=r, column=2).value  # 获取app名字(中文)
            apk_url = table.cell(row=r, column=3).value  # 获取下载地址
            temp_str = apk_name + ";" + apk_url  # 不可以put列表进队列,只能尝试put字符串
            q.put(temp_str)  
        
        for i in range(10):  # 开启10个线程
            DownLoadThread(q).start()
    

    本案例练手素材下载

    跳转至自拍教程官网下载素材
    武散人出品, 请放心下载并使用。

    运行方式与效果

    比如保存以上代码为download_1000apk.py并放在桌面,
    建议python download_1000apk.py运行,当然也可以双击运行。
    运行效果如下:


    更多更好的原创文章,请访问官方网站:www.zipython.com
    自拍教程(自动化测试Python教程,武散人编著)
    原文链接:https://www.zipython.com/#/detail?id=32fc6017b5e14784a862c95367967ebd
    也可关注“武散人”微信订阅号,随时接受文章推送。

  • 相关阅读:
    一步步构建大型网站架构
    程序员技术练级攻略
    再谈“我是怎么招聘程序员的”
    os.path.basename()
    用pymysql实现的注册登录公告练习
    缓冲(cache)和缓存(buffer)
    数据库视图,触发器,事务,存储过程,函数,备份与恢复
    mysql用户管理和pymysql
    mysql重点,表查询操作和多表查询
    数据库的约束语句和表之间的关系
  • 原文地址:https://www.cnblogs.com/zipython/p/12642542.html
Copyright © 2011-2022 走看看