Python + Selenium 小技巧之上传下载文件
01 文件的上传
上传文件的操作,也是很为常用的Web功能之一,但WebDriverAPI并没有为我们提供专门用于上传文件的方法。所以我们要另寻途径来实现它。
在Web页面中,文件上传操作一般需要单击“上传”按钮,然后在打开的本地Windows窗口中选择本地文件进行上传。因为WebDriver无法操作Windows控件,所以对于首先要解决的是如何识别Windows控件这个问题上。
在Web页面中,一般通过以下两种方式实现文件上传。
- 普通上传,将本地文件路径 作为一个值放在input标签中,通过form表单,将这个值提交给服务器。
- 插件上传,一般是指基于Flash、JavaScript或Ajax等技术实现的上传功能。
对于通过input标签实现的上传功能,可以将其看作一个输入框,即通过send_keys()
本地文件路径的方式实现文件上传。
import os
from selenium import webdriver
file_path = os.path.abspath('./files/')
browser = webdriver.Chrome()
upload_page = 'files:///' + file_path + 'upfile.html'
browser.get(upload_page)
# 定位上传按钮,添加本地文件
browser.find_element_by_id("file").send_keys(file_path + 'uploadtest.txt')
# ……
通过这种方法来上传文件,可以避免操作Windows控件。
而对于插件上传,我们可以借助AutoIt来实现。稍后在更新文章时会详细说明。
02 下载文件
WebDriver允许我们设置默认的文件下载路径,也就是说,文件会自动且存放到设置的目录中,不同的浏览器设置方式不同。
2.1 Firefox浏览器中下载文件
我们先来看看Firefox浏览器中下载文件的实现:
import os
from selenium import webdriver
fp = webdriver.FirefoxProfile()
fp.set_preference("browser.download.folderList", 2)
fp.set_preference("browser.download.dir", os.getcwd())
fp.set_preference("browser.helperApps.neverAsk.saveToDisk", "binary/octet-stream")
driver = webdriver.Firefox(firefox_profile=fp)
driver.get("https://pypi.org/project/selenium/#files")
driver.find_element_by_partial_link_text("selenium-3.141.0.tar.gz").click()
- browser.download.folderList 用于指定文件下载后的存放目录。设置为0,表示文件会下载到浏览器设置的默认路径;设置为2,表示文件会下载到自定义的路径。
- browser.download.dir 用于设置自定义存放路径。本例中通过
os.getcwd()
方法获取当前文件的所在位置,即下载文件保存的目录。 - browser.helperApps.neverAsk.saveToDisk 指定要的类型,即
Content-type
值,”binary/octet-stream”用于表示二进制文件。
更多关于HTTP Content-type对照表,参见:http://tool.oschina.net/commons
当然,也可以通过在Firefox浏览器地址栏输入“about:config”进行参数的设置。
在调用WebDriver的Firefox类时,将所有设置选项作为firefox_profile参数Firefox浏览器。浏览器在会根据这些文件下载到当前脚本目录下。
2.2 Chrome浏览器中下载文件
在Chrome浏览器中下载文件的思路也是类似的,可以在打开浏览器之前,预设一些自定义参数。
import os
from selenium import webdriver
options = webdriver.ChromeOptions()
prefs = {'profile.default_content_settings.popups': 0, 'dowload.default_directory': os.getcwd()}
options.add_experimental_option('prefs', prefs)
driver = webdriver.Chrome(chrome_options=options)
driver.get("https://pypi.org/project/selenium/#files")
driver.find_element_by_partial_link_text("selenium-3.141.0.tar.gz").click()
- profile.default_content_settings.popups 设置为0,表示禁止下载窗口。