首页 > 其他分享 >Selenium4Web自动化7-文件上传和日期控件

Selenium4Web自动化7-文件上传和日期控件

时间:2022-10-24 15:34:50浏览次数:97  
标签:pyautogui 控件 鼠标 Selenium4Web driver import 上传

一、文件上传操作-input标签文件选择

当input元素为文件类型时, 文件上传对话框可以使用Selenium处理. 文件上传的代码实现如下

from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
driver = webdriver.Chrome(ChromeDriverManager().install())
driver.implicitly_wait(10)
driver.get("https://the-internet.herokuapp.com/upload");
driver.find_element(By.ID,"file-upload").send_keys("selenium-snapshot.jpg")
driver.find_element(By.ID,"file-submit").submit()
if(driver.page_source.find("File Uploaded!")):
    print("file upload success")
else:
    print("file upload not successful")
driver.quit()

二、文件上传操作-非input标签文件选择

当上传文件按钮不是input标签时,比如下图的前端框架layui(一个JS框架)上传按钮就是button标签,selenium无法处理文件上传。

那么对于那些不是input框实现的上传怎么办,这种上传千奇百怪,有用a标签的,有用div的,有用button的,有用object的,我们没有办法通过直接在网页上处理掉这些上传,唯一的办法就是打开windows的系统弹框,去处理弹框。
解决办法很简单,用OS层面的操作去处理。这里经过多种库的调用,找到一个适用性最好,学习起来最简单的库PyAutoGui来解决上传问题。
当然网上还有很多方法,有兴趣的可以去看看,这里贴一下链接,对比下来就会知道PyAutoGui才是更简单易用以及实用的解决方案。
Selenium+Python上传文件方法:
https://www.jianshu.com/p/fba37cc5d5e2

1. PyAutoGui入门

官方文档链接:
https://pyautogui.readthedocs.io/en/latest/

PyAutoGUI 让您的 Python 脚本控制鼠标和键盘以自动与其他应用程序交互。API 的设计很简单。PyAutoGUI 适用于 Windows、macOS 和 Linux,并在 Python 2 和 3 上运行。

要使用 pip 安装:pip install pyautogui

PyAutoGUI 有如下几块功能:
移动鼠标并单击其他应用程序的窗口。
向应用程序发送击键(例如,填写表格)。
截取屏幕截图,并给出一个图像(例如,一个按钮或复选框),然后在屏幕上找到它。
找到应用程序的窗口,然后移动、调整大小、最大化、最小化或关闭它(目前仅限 Windows)。
显示警报和消息框。

1.1 入门代码案例

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pyautogui
from time import sleep

# Get the size of the primary monitor.
# 获取主监视器的大小
# screenWidth, screenHeight = pyautogui.size()
# print(screenWidth, screenHeight)
#
# # Get the XY position of the mouse.
# # 获得鼠标的XY坐标(演示的是扩展屏,所以X坐标>1920了)
# currentMouseX, currentMouseY = pyautogui.position()
# print(currentMouseX, currentMouseY)
#
# # Move the mouse to XY coordinates.
# # 移动鼠标到指定的坐标
# pyautogui.moveTo(3800, 613)
#
# # Click the mouse.
# # 点击鼠标
# pyautogui.click()
#
# # Move the mouse to XY coordinates and click it.
# # 移动鼠标到坐标然后点击
# pyautogui.click(3800, 513)
#
# # Find where button.png appears on the screen and click it.
# # 找到桌面上名为button.png的图片并点击
# # 代码测试会报错:TypeError: cannot unpack non-iterable NoneType object
# # pyautogui.Click('button.png')
#
# # Move the mouse 400 pixels to the right of its current position.
# # 从当前位置右移鼠标400PX
# pyautogui.move(400, 0)
#
# # Double click the mouse.
# # 双击鼠标
# pyautogui.doubleClick()
#
# # Use tweening/easing function to move mouse over 2 seconds.
# # 使用渐变/缓动功能移动鼠标,间隔2秒。
# # 坐标是目标坐标,从当前位置移动过去,2秒停顿一下(方便看移动过程)
# pyautogui.moveTo(500, 500, duration=2, tween=pyautogui.easeInOutQuad)

# type with quarter-second pause in between each key
# 输入文本,每次按键间隔0.25秒
# 案例:新建txt文档演示
# pyautogui.write('Hello world!', interval=0.25)

# Press the Esc key. All key names are in pyautogui.KEY_NAMES
# 案例:选中代码然后取消
# pyautogui.press('esc')
# pyautogui.KEY_NAMES

# Press the Shift key down and hold it.
# 按下Shift键不放
# with pyautogui.hold('shift'):
#         # Press the left arrow key 4 times.
#         # 按左键4次
#         pyautogui.press(['left', 'left', 'left', 'left'])  # Press the left arrow key 4 times.
# Shift键会自动释放
# Shift key is released automatically.

# Press the Ctrl-C hotkey combination.
# 按Ctrl-C组合键
# pyautogui.hotkey('ctrl', 'c')

# Make an alert box appear and pause the program until OK is clicked.
# 生成一个弹窗并暂停程序,直到点击Ok按钮
# pyautogui.alert('This is the message to display.')

1.2 例子,在画图中以方形螺旋拖动鼠标

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pyautogui
from time import sleep

sleep(5)

distance = 200
while distance > 0:
        pyautogui.drag(distance, 0, duration=0.5)   # 右移
        distance -= 5
        pyautogui.drag(0, distance, duration=0.5)   # 下移
        pyautogui.drag(-distance, 0, duration=0.5)  # 左移
        distance -= 5
        pyautogui.drag(0, -distance, duration=0.5)  # 上移

1.3 应用PyAutoGui实现文件上传

通过直接操控鼠标键盘,是很容易实现文件上传的,只要能快速获得坐标即可,下面的代码可以实时获取鼠标的坐标

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import time
import pyautogui as pag
try:
    while True:
        print("Press Ctrl-C to end")
        screenWidth, screenHeight = pag.size()  #获取屏幕的尺寸
        print(screenWidth,screenHeight)
        x,y = pag.position()   #获取当前鼠标的位置
        # Python rjust() 返回一个原字符串右对齐,并使用空格填充至长度 width 的新字符串。
        # 如果指定的长度小于字符串的长度则返回原字符串。
        posStr = "Position:" + str(x).rjust(4)+','+str(y).rjust(4)
        print(posStr)
        time.sleep(0.2)
        os.system('cls')   #清除屏幕
except KeyboardInterrupt:
    print('end....')

如下图,运行代码后,不要停,控制台会实时输出鼠标所在位置的坐标,类似于页面元素定位了,只是这里换成了坐标。

有了坐标,就可控制鼠标和键盘在屏幕中的指定位置进行文件上传操作了。

三、日期控件

1 可输入日期控件

一般的日期控件是可以直接输入日期的,如果使用webdriver 去设置日期,

  1. 定位到该日期控件
  2. 使用sendKeys 方法
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from time import sleep
from selenium.webdriver.support import expected_conditions as ec

driver = webdriver.Chrome()
wait = WebDriverWait(driver,10)

driver.get("https://layuion.com/demo/laydate.html")


# 移动窗口
driver.set_window_position(1900,-200)
driver.set_window_size(1550,1000)

# 定位到日期控件,并输入
locator = (By.XPATH,'//input[@id="test1"]')
wait.until(ec.visibility_of_element_located(locator)).send_keys("2022-09-30")

2 readonly日期控件

有的日期控件是readonly的
比如:

<input class="form-control getTime ng-touched valid ng-valid-parse ng-valid ng-valid-required ng-pristine" type="text" required="" name="establish_time" ng-model="addStationInfo.establish_time" ng-readonly="true" readonly="readonly"/>

这个时候,没法调用WebElement的sendKeys()
方法1:可以使用JS remove readonly attribute,然后sendKeys

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

"""
<input class="form-control getTime ng-touched valid ng-valid-parse ng-valid ng-valid-required ng-pristine" 
type="text" required="" name="establish_time" ng-model="addStationInfo.establish_time" ng-readonly="true" 
readonly="readonly"/>
"""
js = 'document.getElementByName("establish_time").removeAttribute("readonly")'
driver.execute_script(js)

# 在sendKeys之前应该清空原来的默认值
driver.find_element(By.NAME,"establish_time").clear()
driver.find_element(By.NAME,"establish_time").send_keys("2033-08-03")

如果输入完日期,并无法触发查询动作,可以点击日期输入框,调出日历控件,点击“确认”按钮,即可触发

方法2:使用js方法,输入日期,直接改掉输入框元素的值即可

#去掉元素的readonly属性
js = 'document.getElementByName("establish_time").removeAttribute("readonly");'
driver.execute_script(js)
 
#使用js方法输入日期
js_value = 'document.getElementByName("establish_time").value = "2020-05-28"'
driver.execute_script(js_value)

目前很少有使用readonly的日期控件了,没有相应的案例。

3 日期控件在frame里

操作思路:
1、切换到iframe;
2、完成相关操作;
3、返回主文档

iframes=browser.find_elements_by_css_selector('iframe')
browser.switch_to.frame(iframes[0])
ny=browser.find_element_by_xpath('//*[@id="ny"]')
ny.click()
time.sleep(1)
ny.send_keys('202106')
time.sleep(1)
#从frame中切回主文档
browser.switch_to.default_content() 

4 非readonly,也无法直接输入的日期控件

这种,基本只能靠鼠标点击和鼠标滚动日期控件来完成了。会存在一些看不到的元素,就要用到最新学到的Selenium4的滚轮

如上图,最下面的23时和59分、59秒,都是不可见的,需要滚动到下面

# 修改分钟,改成59
locater = (By.XPATH,"//p[contains(text(),'分')]/../ol/li[60]")
# 基于元素,按给点数值滚动
min = driver.find_element(By.XPATH, "//p[contains(text(),'分')]/../ol")
# 定义滚动起始元素
scroll_origin = ScrollOrigin.from_element(min)
min59 = driver.find_element(*locater)
# 按住不动,滚动指定数值成功
ActionChains(driver) \
    .scroll_to_element(min)\
    .click_and_hold(min)\
    .scroll_from_origin(scroll_origin,0,1800) \
    .release(min)\
    .move_to_element(min59)\
    .click()\
    .perform()

如果ActionChains不能解决问题,还可以考虑使用PyAutoGui,用坐标进行定位并点击。

标签:pyautogui,控件,鼠标,Selenium4Web,driver,import,上传
From: https://www.cnblogs.com/cekailsf/p/16821589.html

相关文章

  • 上传文件异常 FileInputStream ByteArrayInputStream
    问题文件上传的时候遇到如下异常java.lang.ClassCastException:java.io.ByteArrayInputStreamcannotbecasttojava.io.FileInputStream出错的代码:FileOutputStrea......
  • JS文件动态上传进度条
    原网站<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="viewport......
  • # vue 实现文件切上传
    vue实现文件切上传在实际开发项目过程中有时候需要上传比较大的文件,然后呢,上传的时候相对来说就会慢一些,so,后台可能会要求前端进行文件切片上传,很简单哈,就是把比如说1个......
  • SAP UI5 的 TimePicker ,一个钟表外观的时间选择控件试读版
    一套适合SAPUI5初学者循序渐进的学习教程本专栏计划的文章数在​​300​​​篇左右,到​​2022年10月14日​​​为止,目前已经更新了​​141​​​篇,专栏完成度为​......
  • qt 查看控件类型
    qt的大部分控件都是基于QWidget的,所以有时需要通过一种方法判断获取到的Widget是哪种类型的控件;解决文案是:QWidget->metaObject()->className(),例如:ui->label->meta......
  • 采集文章图片,上传到本地或者七牛云
    最近写了一个新需求,要求是采集回来的文章,图片替换成自己的url,可以选择保存本地或者七牛云七牛云原方案是下载到本地,但是获取不到,就作罢了,改用七牛云异步第三方资源抓取的......
  • SpringMCV(八):文件上传
    一、导入相关依赖<dependencies><!--文件上传--><dependency><groupId>commons-fileupload</groupId><artifactId>com......
  • devexpress中grid控件教程 多线程异步加载数据,进度条展示
    devexpress中最强大的控件,要数它的Grid了。几乎任务数据都可以展示,但今天要用它做另一个功能。假设我们开发这样一款软件:视频编辑软件。里面有个功能,提取视频中的音频。一......
  • 前端base64编码格式图片转换为file类型并上传
    将前端的base64编码格式图片转换为file文件,方便传输到后台进行处理。/*将base64转换为blob*/functionbase64ToBlob(dataurl){vararr=dataurl.split(',');var......
  • Oss图片上传的功能
    Oss的图片上传工具类获取oss的四个参数Stringendpoint=ConstantPropertiesUtils.END_POINT;StringaccessKeyId=ConstantPropertiesUtils.KEY_ID;......