最近搞app自动化测试,需要自动从网页上下载apk用于测试,顺便学习了几种从web下载文件的方式。
一、PowerShell DownloadFile 命令
PowerShell 是一种winodws原生的脚本语言,使用很方便,可以实现很多复杂的功能。
首先启动PowerShell,可以在cmd里执行 start powershell,也可以按住shift建右击选择打开powershell
启动powershell后输入如下命令:
$client = new-object System.Net.WebClient $client.DownloadFile('url', 'file')
这里的url是下载文件的地址,file是文件保存路径(包括文件名)。如果出现报错如下:使用“2”个参数调用“DownloadFile”时发生异常:“在 WebClient 请求期间发生异常。”
就是文件保存路径没有写完整,一定要包括文件名。如:D:app-release.apk
在Jenkins build step 中执行 PowerShell 命令
当然这是手动在powershell命令行执行的,并没有实现自动化。我们需要把它放到Jenkins中去实现。
在Jenkins中执行powershell命令需要先安装相应插件如下:
安装完重启,就可以在任务构建中添加执行powershell命令的操作:
填入上面的两条命令,就可以执行文件下载操作了。
多个build step
如果有多个step呢?如果想要在下载文件失败后进行其他操作呢?
上面的操作,无论怎么执行 PowerShell 命令,build step 的结束状态都是 "成功"(包括一些命令执行失败的情况)。这是因为PowerShell 执行的过程中没有执行 exit 调用,Jenkins 无法判断执行的命令是否成功退出,所以就默认是成功的了。实际上,当命令执行失败或是满足一些条件时,我们希望 build step 的结束状态是 "失败",后续的 build step 根据前面 step 的结束状态决定是否执行。
这就需要在PowerShell 命令执行后执行 exit 调用:判断脚本执行成功时调用 exit 0;判断脚本执行失败时调用 exit 1
也就是执行三条命令,例如:
$client = new-object System.Net.WebClient $client.DownloadFile('url', 'file') exit 1
二、python实现文件下载
利用python+selenium也可以实现从web上下载文件,首先要确保对应调用的浏览器安装好driver,参考:https://www.cnblogs.com/Dahlia/p/10655573.html
chrome下载
对于Chrome浏览器,设置其options:
- download.default_directory:设置下载路径
- profile.default_content_settings.popups:设置为 0 禁止弹出窗口
代码示例:
# -*- coding: utf-8 -*- from selenium import webdriver from time import sleep options = webdriver.ChromeOptions() prefs = {'profile.default_content_settings.popups': 0, 'download.default_directory': 'd:\'} options.add_experimental_option('prefs', prefs) driver = webdriver.Chrome(executable_path='D:\chromedriver.exe', chrome_options=options) driver.get('http://sahitest.com/demo/saveAs.htm') driver.find_element_by_xpath('//a[text()="testsaveas.zip"]').click() sleep(3) driver.quit()
firefox下载
同样,对于Firefox,需要我们设置其Profile:
- browser.download.dir:指定下载路径
- browser.download.folderList:设置成2,表示使用自定义下载路径;设置成0,表示下载到桌面;设置成1,表示下载到默认路径
- browser.download.manager.showWhenStarting:在开始下载时是否显示下载管理器
- browser.helperApps.neverAsk.saveToDisk:对所给出文件类型不再弹出框进行询问
代码示例:
# -*- coding: utf-8 -*- from selenium import webdriver from time import sleep profile = webdriver.FirefoxProfile() profile.set_preference('browser.download.dir', 'd:\') profile.set_preference('browser.download.folderList', 2) profile.set_preference('browser.download.manager.showWhenStarting', False) profile.set_preference('browser.helperApps.neverAsk.saveToDisk', 'application/zip') driver = webdriver.Firefox(firefox_profile=profile) driver.get('http://sahitest.com/demo/saveAs.htm') driver.find_element_by_xpath('//a[text()="testsaveas.zip"]').click() sleep(3) driver.quit()
firefox下载有个要注意的地方:
browser.helperApps.neverAsk.saveToDisk这个参数是对所给出文件类型不再弹出框进行询问,需要明确一下对应文件的MIME类型,参考:http://www.w3school.com.cn/media/media_mimeref.asp
在实践的时候下载的是apk文件,发现这里没列出apk的MIME类型。查阅其他资料发现,apk对应:application/vnd.android.package-archive。
以上两个方法稍微优化一下:
# -*- coding: utf-8 -*- from selenium import webdriver from time import sleep import os class WebDownload: chromedriver_path = 'E:\chromedriver\chromedriver.exe' down_dir = 'E:\RED\workspace\appAuto\apk\Android10' file_name = 'app.apk' url = 'https://www.xxx' def chrome_download(self): list = os.listdir(self.down_dir) #列出目录的下所有文件和文件夹 if self.file_name in list: os.remove(os.path.join(self.down_dir,self.file_name)) # download.default_directory:设置下载路径 # profile.default_content_settings.popups:设置为 0 禁止弹出窗口 options = webdriver.ChromeOptions() prefs = {'profile.default_content_settings.popups': 0, 'download.default_directory': self.down_dir} options.add_experimental_option('prefs', prefs) driver = webdriver.Chrome(executable_path=self.chromedriver_path, chrome_options=options) driver.get(url=self.url) driver.find_element_by_id('down_load').click() sleep(20) driver.quit() def firefox_download(self): list = os.listdir(self.down_dir) # 列出目录的下所有文件和文件夹 if self.file_name in list: os.remove(os.path.join(self.down_dir, self.file_name)) # browser.download.dir:指定下载路径 # browser.download.folderList:设置成2,表示使用自定义下载路径;设置成0,表示下载到桌面;设置成1,表示下载到默认路径 # browser.download.manager.showWhenStarting:在开始下载时是否显示下载管理器 # browser.helperApps.neverAsk.saveToDisk:对所给出文件类型不再弹出框进行询问。apk:application/vnd.android.package-archive profile = webdriver.FirefoxProfile() profile.set_preference('browser.download.dir', self.down_dir) profile.set_preference('browser.download.folderList', 2) profile.set_preference('browser.download.manager.showWhenStarting', False) profile.set_preference('browser.helperApps.neverAsk.saveToDisk', 'application/vnd.android.package-archive') driver = webdriver.Firefox(firefox_profile=profile) driver.get(self.url) driver.find_element_by_id('down_load').click() sleep(20) driver.quit() if __name__ == '__main__': # WebDownload().chrome_download() WebDownload().firefox_download()