Selenium:上传、下载文件

Selenium:上传、下载文件

1、上传文件是比较常见的Web功能之一。比如:常见的上传头像功能

2、对于Web页面的上传功能实现一般有以下两种方式:
    ⑴普通上传:普通的附件上传是将本地文件的路径作为作为一个值放在input标签中,通过form表单将这个值提交给服务器
    ⑵插件上传:一般是指基于Flash、JS或AJAX等技术所实现的上传功能
    ⑶也就是说文件上传分为两种方式:一种是input标签的,一种是非input标签的

3、一般Web页面的上传功能的操作是:单击"上传"按钮后打开本地Windows窗口,从窗口中选择本地文件进行上传
    ⑴这个过程中打开的Windows窗口是属于Windows控件,不是浏览器的
    ⑵WebDriver是无法操作Windows控件的,因此WebDriver并没有提供专门用于上传文件的接口方法

input标签上传

1、前面介绍了文件上传分为两种方式:一种是input标签的,一种是非input标签的

2、对于使用input标签实现的Web上传功能,在Selenium中就比较简单了,可以直接使用send_keys()方法进行模拟
    ⑴对于通过input标签实现的上传功能,可以将其看做是一个输入框,只是以按钮的形式表现出来的
    ⑵注:这种上传方式定位、操作的是"上传"按钮,因此页面上得有"上传"类按钮

3、通过input标签实现的上传功能有两个比较显著的特点
    ⑴页面中存在"上传"等按钮
    ⑵按钮是input标签

例1:上传百度头像
Selenium:上传、下载文件_第1张图片

from selenium import webdriver
import time
from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Chrome()
# 设置浏览器窗口大小
driver.maximize_window()
# 进入百度首页
driver.get('https://www.baidu.com')
# 点击登录
driver.find_element_by_id("s-top-loginbtn").click()
time.sleep(3)
# 输入用户名、密码并点击登录
driver.find_element_by_id("TANGRAM__PSP_11__userName").send_keys("账号")
driver.find_element_by_id("TANGRAM__PSP_11__password").send_keys("密码")
driver.find_element_by_id("TANGRAM__PSP_11__submit").click()
time.sleep(10)
# 将鼠标悬停在设置按钮
ActionChains(driver).move_to_element(driver.find_element_by_xpath('//*[@id="s-top-username"]/span[2]')).perform()
# 点击账号设置
driver.find_element_by_xpath('/html/body/div[1]/div[2]/div[3]/div[2]/a[2]').click()
# 切换到设置窗口页面
driver.switch_to.window(driver.window_handles[1])
time.sleep(3)
# 点击修改头像
driver.find_element_by_xpath('//*[@id="app"]/div[1]/div/div[3]/div/div/div[1]/img').click()
# 切换到修改头像窗口页面
driver.switch_to.window(driver.window_handles[2])
time.sleep(5)
# 使用send_keys()方法上传文件
driver.find_element_by_id('fileImg').send_keys('F:\\1.jpg')

注:
1、上面例子在进行登录时,会涉及到图形验证,这步骤需要手动操作,可以将等待时间设置长点,方便手动验证

2、在使用Selenium操作浏览器时,操作步骤最好尽量与手动操作浏览器步骤一样:避免找不到元素等
    ⑴特别是对于下拉框这种:最好先悬浮或点击下拉按钮,等下拉框中的元素展示出来后再点击下拉框中的元素
    ⑵反正就是Selenium操作尽量与手动操作一致

例2:

Selenium:上传、下载文件_第2张图片

import time
from selenium import webdriver

driver = webdriver.Chrome()
# 设置浏览器窗口大小
driver.maximize_window()
# 进入百度首页
driver.get('https://www.baidu.com')
# 切换到图片搜索框
driver.find_element_by_class_name("soutu-btn").click()
# 上传图片
driver.find_element_by_class_name("upload-pic").send_keys('F:\\1.jpg')

非input标签上传

1、前面介绍了input标签上传完文件的实现
    ⑴input标签上传实际上是通过输入框的send_keys()方法来实现的,不会涉及到Windows控件,所以比较好实现

2、如果上传功能不是input标签实现的,那么就需要操作对应的Windows控件了
    ⑴Selenium并不能操作Windows控件,因此可以借助第三方工具来进行操作了,比如一些Windows自动化库或工具
        ①Python第三方库:pywinauto
        ②其他工具:Autolt

3、pywinauto:是用于控制Windows上的控件来做一些自动化操作的库,它允许将鼠标和键盘操作发送到窗口对话框和控件,来完成Windows GUI(图形用户界面)的自动化操作
    ⑴这个是Python的第三方库,可以直接使用pip安装

4、Autolt:是一个使用BASIC语言编写的免费软件,用来进行Windows GUI(图形用户界面)的自动化操作
    ⑴这是一个独立的软件,感觉使用起来有点麻烦。有兴趣的可以自己去了解下

例3:

Selenium:上传、下载文件_第3张图片

import time
import pywinauto
from selenium import webdriver

driver = webdriver.Chrome()
# 设置浏览器窗口大小
driver.maximize_window()
# 进入页面
driver.get('https://www.jq22.com/yanshi17984')
# 切换到iframe
driver.switch_to.frame("iframe")
driver.find_element_by_class_name('addImg').click()
time.sleep(2)
# 通过窗口打开
app = pywinauto.Desktop()
# 通过弹框名称进入控件中
win = app['打开']
# 输入上传图片的地址
# 这里文件路径不能写'F:\\1.jpg',因为这个是传给Windows的,而windows识别不了两个\\
win['Edit'].type_keys(r'F:\1.jpg')
#点击打开按钮
win['Button'].click()

"""
这个例子在执行是会报:RuntimeError: SendInput() inserted only 0 out of 2 keyboard events
百度了下,感觉是pywinauto和Python位数不一致的原因导致
这里只是给一个上传完文件的处理思路
"""

注:所以在使用Selenium模拟上传功能时,一定要分清楚网页中的上传功能时通过哪种技术实现的

下载文件

1、在日常的Web操作中,经常会遇到文件下载操作
    ⑴文件下载其实没有什么特殊的,一般都是点击一个下载链接,然后自动下载到默认目录

2、所以对于使用Selenium来模拟下载文件也只是点击一个元素的操作

例4:下载到默认目录

import time
from selenium import webdriver

chrome_options = webdriver.ChromeOptions()
chrome_options.add_experimental_option("excludeSwitches", ['enable-automation'])
# 打开浏览器
driver = webdriver.Chrome(options=chrome_options)
# 设置浏览器窗口大小
driver.maximize_window()
# 进入页面
driver.get('https://pypi.org/project/selenium')
# 点击下载;链接
driver.find_element_by_id("files-tab").click()
driver.find_element_by_xpath('//*[@id="files"]/div/div[2]/a[1]').click()

# 这个例子中下载文件时未进行配置,所以会将文件下载到浏览器下载的默认目录中

设置火狐浏览器启动配置

1、WebDriver允许我们设置默认的文件下载路径,也就是说,文件会自动下载并且会存放到设置的目录中

2、其实这个过程最重要的就是要知道如何设置浏览器参数(配置)

例5:

import os
from selenium import webdriver

# 设置浏览器配置
profile = webdriver.FirefoxProfile()
# 置成0代表下载到浏览器默认下载路径,设置成2则可以保存到指定的目录
profile.set_preference('browser.download.folderList', 2)
# 指定存放目录
profile.set_preference('browser.download.dir', 'd:\\')  #现在文件存放的目录
# 是否显示开始:True为显示开始,Flase为不显示开始
profile.set_preference('browser.download.manager.showWhenStarting', False)
#对所给文件类型不再弹出框进行询问
profile.set_preference('browser.helperApps.neverAsk.saveToDisk', 'application/octet-stream')
# 以指定配置启动浏览器
driver = webdriver.Firefox(firefox_profile=profile)
# 设置浏览器窗口大小
driver.maximize_window()
# 进入页面
driver.get('https://pypi.org/project/selenium')
# 点击下载;链接
driver.find_element_by_id("files-tab").click()
driver.find_element_by_xpath('//*[@id="files"]/div/div[2]/a[1]').click()

注:

1、关于火狐浏览器的参数,可以通过在Firefox浏览器地址栏中输入"about:config"查看
    ⑴设置好配置信息后,在启动浏览器后,浏览器就会根据这些配置进行运行或操作

2、常用的配置参数有:
    ⑴browser.download.folderList:置成0代表下载到浏览器默认下载路径,设置成2则可以保存到指定的目录
    ⑵browser.download.dir:下载文件存放目录
        ①如果browser.download.folderList=0,那么就不需要设置该参数
    ⑶browser.helperApps.neverAsk.saveToDisk:对所给文件类型不再弹出框进行询问
        ①在下载文件时,浏览器可能会弹出对应的下载提示框
        ②这个提示框是浏览器的,不能使用Selenium进行操作,所以可以通过该配置关闭提示
        ③上面例子中表示:对于下载类型为"application/octet-stream"的文件不需要弹出提示
        ④HTTP下载内容Content-type常用对照表:https://tool.oschina.net/commons
    ⑷browser.download.manager.showWhenStarting:是否显示开始
        ①True为显示开始
        ②Flase为不显示开始

3、上面例子主要是想介绍下如何给浏览器添加参数(配置):在调用WebDriver的Firefox()方法时设置信息会作为参数传递给浏览器。Firefox浏览器在启动、运行(下载)时就会根据这些设置信息进行操作
    ⑴实例化一个配置对象:webdriver.FirefoxProfile()
    ⑵通过配置对象添加配置信息:配置对象.set_preference(key, value)
    ⑶以配置对象启动浏览器:webdriver.Firefox(firefox_profile=配置对象)

设置谷歌浏览器启动配置

1、WebDriver允许我们设置默认的文件下载路径,也就是说,文件会自动下载并且会存放到设置的目录中

2、其实这个过程最重要的就是要知道如何设置浏览器参数(配置)

例6:

import os
from selenium import webdriver

# 设置浏览器配置
options = webdriver.ChromeOptions()
# 设置配置信息:试了下这个变量还必须是prefs,不然会报错,想不通
prefs = {'profile.default_content_settings.popups': 0, 'download.default_directory': 'd:\\'}
# 添加配置信息至配置对象中
options.add_experimental_option('prefs', prefs) #试了下这个变量还必须是prefs,不然会报错,想不通
# 以配置信息启动浏览器
driver = webdriver.Chrome(chrome_options=options)
# 设置浏览器窗口大小
driver.maximize_window()
# 进入页面
driver.get('https://pypi.org/project/selenium')
# 点击下载;链接
driver.find_element_by_id("files-tab").click()
driver.find_element_by_xpath('//*[@id="files"]/div/div[2]/a[1]').click()

注:

1、火狐浏览器添加配置的方式与谷歌浏览器的方式是不一样的,所以需要注意下

2、上面例子中使用到的配置:
    ⑴download.default_directory:设置下载路径
    ⑵profile.default_content_settings.popups:设置为0禁止弹出窗口    

3、谷歌浏览器以指定配置信息启动的步骤:
    ⑴实例化一个配置对象:webdriver.ChromeOptions()
    ⑵通过配置对象添加配置信息:配置对象.add_experimental_option(key, value)
    ⑶以配置对象启动浏览器:webdriver.Chrome(chrome_options=配置对象)

处理HTML5的视频播放

1、目前HTML5技术已经渐渐成为主流,主流的浏览器都已经支持HTML5了
    越来越多的应用都在使用HTML5的元素了,比如canvas、video等

2、WebDriver在指定浏览器上操作HTML5元素

例7:

import time
from selenium import webdriver

# 启动浏览器
driver = webdriver.Chrome()
# 设置浏览器窗口大小
driver.maximize_window()
# 进入页面
driver.get('https://videojs.com/')
# 定位video标签
video = driver.find_element_by_id("vjs_video_3_html5_api")
print(video)
# 返回文件播放地址
url = driver.execute_script("return arguments[0].currentSrc;", video)
print(url)
# 播放视频10s
print("开始播放")
driver.execute_script("return arguments[0].play()",video)
time.sleep(10)
print("结束播放")
driver.execute_script("return arguments[0].pause()", video)
# 关闭页面
driver.quit()

注:
1、HTML5中定义了新元素


 

你可能感兴趣的:(Selenium,python)