用python批量下载apk


Posted in Python onDecember 29, 2020

案例故事:

之前我们做Android手机测试的时候,

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

用python批量下载apk

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

准备阶段

以上excel里的的url分明是需要进行二次重定向的,因为其不是一个.apk结尾的链接,
我们需要进行解析后再进行重定向。wget命令是不支持这url重定向解析的,所以不能采用。
所以我们还是采用requests模块来实现下载。

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

记住批处理脚本的精髓:批量顺序执行语句,
由于批处理脚本形式只能实现单个apk的下载任务,我们使用requests模块实现下载。
单线程效率比较慢,必须等前一个apk下载完毕后,才会开始后一个apk的下载。

# 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面向对象类形式 多线程下载的写法

准备阶段

多线程一般效率快很多很多,
多线程任务执行,一般是将apk下载任务放到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运行,当然也可以双击运行。
运行效果如下:

用python批量下载apk

以上就是用python批量下载apk的详细内容,更多关于python批量下载apk的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
在Python中利用Into包整洁地进行数据迁移的教程
Mar 30 Python
Python函数的周期性执行实现方法
Aug 13 Python
Python模拟鼠标点击实现方法(将通过实例自动化模拟在360浏览器中自动搜索python)
Aug 23 Python
python利用高阶函数实现剪枝函数
Mar 20 Python
Python 找到列表中满足某些条件的元素方法
Jun 26 Python
python的常用模块之collections模块详解
Dec 06 Python
对Python Class之间函数的调用关系详解
Jan 23 Python
Django学习笔记之为Model添加Action
Apr 30 Python
pyqt5 删除layout中的所有widget方法
Jun 25 Python
Python celery原理及运行流程解析
Jun 13 Python
Python爬取酷狗MP3音频的步骤
Feb 26 Python
Python if else条件语句形式详解
Mar 24 Python
python如何调用php文件中的函数详解
Dec 29 #Python
详解Open Folder as PyCharm Project怎么添加的方法
Dec 29 #Python
pycharm如何设置官方中文(如何汉化)
Dec 29 #Python
详解Pycharm第三方库的安装及使用方法
Dec 29 #Python
Django2.1.7 查询数据返回json格式的实现
Dec 29 #Python
Python 获取异常(Exception)信息的几种方法
Dec 29 #Python
python 将html转换为pdf的几种方法
Dec 29 #Python
You might like
PHP,ASP.JAVA,JAVA代码格式化工具整理
2010/06/15 PHP
php URL验证正则表达式
2011/07/19 PHP
php中把美国时间转为北京时间的自定义函数分享
2014/07/28 PHP
php中数据库连接方式pdo和mysqli对比分析
2015/02/25 PHP
如何用javascript判断录入的日期是否合法
2007/01/08 Javascript
javaScript Array(数组)相关方法简述
2009/07/25 Javascript
当鼠标移动到图片上时跟随鼠标显示放大的图片效果
2013/06/06 Javascript
javascript数组遍历for与for in区别详解
2014/12/04 Javascript
Javascript定义类(class)的三种方法详解
2015/03/13 Javascript
jquery实现TAB选项卡鼠标经过带延迟效果的方法
2015/07/27 Javascript
JavaScript实现的简单烟花特效代码
2015/10/20 Javascript
全面解析Bootstrap图片轮播效果
2015/12/03 Javascript
js操作cookie保存浏览记录的方法
2015/12/25 Javascript
javascript基础语法——全面理解变量和标识符
2016/06/02 Javascript
jQuery实现调整表格单列顺序完整实例
2016/06/20 Javascript
Centos7 中 Node.js安装简单方法
2016/11/02 Javascript
jQuery中Datatables增加跳转到指定页功能
2017/02/08 Javascript
jquery中绑定事件的异同
2017/02/28 Javascript
Angularjs 实现动态添加控件功能
2017/05/25 Javascript
vue项目中axios使用详解
2018/02/07 Javascript
JS数组Object.keys()方法的使用示例
2019/06/05 Javascript
图解NodeJS实现登录注册功能
2019/09/16 NodeJs
[05:31]DOTA2英雄梦之声_第08期_莉娜
2014/06/23 DOTA
Python素数检测实例分析
2015/06/15 Python
python里运用私有属性和方法总结
2019/07/08 Python
python利用openpyxl拆分多个工作表的工作簿的方法
2019/09/27 Python
使用python创建生成动态链接库dll的方法
2020/05/09 Python
利用Python实现Excel的文件间的数据匹配功能
2020/06/16 Python
matplotlib自定义鼠标光标坐标格式的实现
2021/01/08 Python
HTML5的download属性详细介绍和使用实例
2014/04/23 HTML / CSS
HTML5 CSS3实现一个精美VCD包装盒个性幻灯片案例
2014/06/16 HTML / CSS
荷兰皇家航空公司官方网站:KLM Royal Dutch Airlines
2017/12/07 全球购物
石油大学毕业生自荐信
2014/01/28 职场文书
卫生安全检查制度
2014/02/04 职场文书
毕业论文致谢词
2015/05/14 职场文书
详解SpringBoot异常处理流程及原理
2021/06/21 Java/Android