English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Resumen de métodos de carga de archivos en selenium de Python

La carga de archivos es un problema que todos los tests de automatización de UI deben enfrentar, hoy aquí el autor comparte su experiencia en el manejo de la carga de archivos, esperando poder ayudar a todos los seleniumer que han caído en el agujero de la carga de archivos.

Primero, debemos distinguir el tipo de botón de carga, que se puede dividir大致mente en dos: uno es el cuadro de entrada, y el otro es más complejo, implementado a través de js, flash, etc., etiqueta no input

Vamos a analizar这两种分别:

1.etiqueta input

Es bien conocido que las etiquetas input pueden ser enviadas directamente con send_keys, aquí no es una excepción, veamos un ejemplo de código:

Ejemplo de URL: http://www.sahitest.com/demo/php/fileUpload.htm

代码:

# -*- coding: utf-8 -*-
from selenium import webdriver
driver = webdriver.Firefox()
driver.get('http:)//sahitest.com/demo/php/fileUpload.htm')
upload = driver.find_element_by_id('file')
upload.send_keys('d:\\baidu.py') # send_keys
print upload.get_attribute('value') # verificar valor
driver.quit()

Resultado:

baidu.py

Es obvio que para la subida de tipo input, send_keys es la solución más simple.

2.subida no input

A continuación, el nivel de dificultad aumentará, ¿qué hacer con las subidas que no son de tipo input? Este tipo de subida es muy variado, hay etiquetas a, div, button, object, no podemos manejar estos subidos directamente en la página web, la única manera es abrir la ventana emergente de OS y manejar la ventana emergente.

El problema surge de nuevo, la capa de la ventana emergente de OS ya no puede ser resuelta por selenium, ¿qué hacer? Es simple, usar operaciones a nivel de OS para manejar, aquí hemos encontrado básicamente la solución al problema.

Hay básicamente las siguientes soluciones:
 1.autoIT, con la ayuda de terceros, llamamos al au generado3o archivo exe.
 2.Python pywin32library, reconoce el manejador de diálogo, y luego opera
 3.SendKeys library
 4.keybd_event, con3Algo similar, pero es una simulación de teclas, ctrl+a, ctrl+c, ctrl+v… 

Sólo conozco las cuatro formas anteriores, si tienes otras, por favor déjame un mensaje para que pueda aprender.

Vamos a ver uno por uno:

1. autoIT

Había hablado sobre los métodos de subida de autoIT y parametrización en otro artículo de blog, por favor consulta selenium autoit command line parameters . No lo repetiré aquí.

2.win32gui

No quiero perder tiempo en palabras, aquí tienes el código primero:

Ejemplo de URL: http://www.sahitest.com/demo/php/fileUpload.htm

代码:

# -*- coding: utf-8 -*-
from selenium import webdriver
import win32gui
import win32con
import time
dr = webdriver.Firefox()
dr.get('http://sahitest.com/demo/php/fileUpload.htm')
upload = dr.find_element_by_id('file')
upload.click()
time.sleep(1)
# win32gui
dialog = win32gui.FindWindow('#32770', u'archivo subido') # Diálogo
ComboBoxEx32 = win32gui.FindWindowEx(dialog, 0, 'ComboBoxEx32', None) 
ComboBox = win32gui.FindWindowEx(ComboBoxEx32, 0, 'ComboBox', None)
Edit = win32gui.FindWindowEx(ComboBox, 0, 'Edit', None) # Buscar sucesivamente los objetos hasta encontrar el manejador del objeto Edit del cuadro de entrada
button = win32gui.FindWindowEx(dialog, 0, 'Button', None) # Determinar el botón Button
win32gui.SendMessage(Edit, win32con.WM_SETTEXT, None, 'd:\\baidu.py') # Ingresar la dirección absoluta en el cuadro de entrada
win32gui.SendMessage(dialog, win32con.WM_COMMAND, 1button) # Presionar el botón button
print upload.get_attribute('value')
dr.quit()

Resultado:

baidu.py

Aquí necesitas una herramienta muy importante: Spy++Hay muchos resultados al buscar en Baidu, por supuesto, también puedes usar las herramientas integradas de autoIT, pero no tan buenas, te recomiendo que descargues una nueva.

y, necesitas instalar pywin32de la biblioteca, puedes ir aaquíEncuentra la biblioteca correspondiente a tu versión de Python, presta atención32La versión es64La versión debe coincidir con la versión de Python que instalaste.

Después de la instalación, puedes ver PyWin en la carpeta de [Inicio] de Python.32de la documentación 【Documentación de Python para Windows】,donde puedes encontrar las API correspondientes a los métodos.

Resumen de algunos usados:

win32gui.FindWindow(lpClassName=None, lpWindowName=None):
 • Comienza a buscar la ventana que coincide con las condiciones desde la ventana superior, y devuelve el identificador de la ventana.
 • lpClassName: Nombre de la clase, en el Spy++allí.
 • lpWindowName: Nombre de la ventana, nombre visible en la barra de título
 • Ejemplo de código para buscar la ventana de carga, puedes usar solo uno de ellos, el classname es más fácil de interferir con otras cosas, el windowname es inestable, el window_name puede ser diferente en diferentes cuadros de diálogo de carga, la forma de ubicar depende de tu situación. 

win32gui.FindWindowEx(hwndParent=0, hwndChildAfter=0, lpszClass=None, lpszWindow=None)
 • Se busca la ventana que coincide con el nombre de la clase y el nombre de la ventana, y se devuelve el identificador de la ventana. Si no se encuentra, se devuelve 0.
 • hwndParent: Si no es 0, se buscan las ventanas hijas del identificador de ventana hwndParent.
 • hwndChildAfter: Si no es 0, se busca según z-; El orden de búsqueda del hwndChildAfter comienza desde hwndChildAfter, de lo contrario, comienza desde la primera ventana hija.
 • lpClassName: Carácter, es el nombre de la clase de la ventana, esto se puede ver en el Spy++allí.
 • lpWindowName: Carácter, es el nombre de la ventana, es decir, el título que puedes ver en la barra de título.
 • Ejemplo de código para buscar el cuadro de entrada y el botón Aceptar en varios niveles 

win32gui.SendMessage(hWnd, Msg, wParam, lParam)
 • hWnd: Entero, identificador de ventana que recibe el mensaje
 • Msg: Entero, mensaje a enviar, estos mensajes están previamente definidos en Windows, puede verlos en los mensajes definidos del sistema (System-Mensajes definidos)
 • wParam: Entero, parámetro wParam del mensaje
 • lParam: Entero, parámetro lParam del mensaje
 • Ejemplo de código para ingresar la dirección del archivo en el cuadro de entrada y hacer clic en el botón Aceptar 

Respecto a win32módulo api y otros métodos, aquí no se describe más, si desea saber más, busque en Baidu o consulte pywin32documentación.

3.SendKeys

Primero debe instalar la biblioteca SendKeys, que se puede instalar con pip

pip install SendKeys 

Ejemplo de código:

Ejemplo de URL: http://www.sahitest.com/demo/php/fileUpload.htm

代码:

# -*- coding: utf-8 -*-
from selenium import webdriver
import win32gui
import win32con
import time
dr = webdriver.Firefox()
dr.get('http://sahitest.com/demo/php/fileUpload.htm')
upload = dr.find_element_by_id('file')
upload.click()
time.sleep(1)
# SendKeys
SendKeys.SendKeys('D:\\baidu.py') # enviar la dirección del archivo
SendKeys.SendKeys("{ENTER}") # enviar tecla Enter
print upload.get_attribute('value')
dr.quit()

Resultado:

baidu.py

A través de la biblioteca SendKeys se puede ingresar información directamente en el punto de foco, sin embargo, debe prestar atención a agregar un poco de tiempo de espera al abrir la ventana, de lo contrario es posible que no se pueda enviar la primera letra (o puede agregar un carácter inútil antes de la dirección), aunque creo que este método es bastante inestable, no se recomienda.

4.keybd_event

win32api proporciona un método keybd_event() para simular pulsaciones de tecla, aunque este método es bastante complicado y no muy estable, por lo que no se recomienda, a continuación se proporciona un ejemplo de parte del código, si desea investigar, busque en Baidu por su cuenta.

# Primero encontrar un cuadro de entrada, ingresar la dirección del archivo que se desea subir, copiar al portapapeles 
video.send_keys('C:\\Users\\Administrator\\Pictures\\04b20919fc78baf41fc993fd8ee2c5c9.jpg')
video.send_keys(Keys.CONTROL, 'a') # selenium's send_keys (ctrl+a)
video.send_keys(Keys.CONTROL, 'x') # (ctrl+x)
driver.find_element_by_id('uploadImage').click() # hacer clic en el botón de subir archivo, abrir el cuadro de diálogo de subida
# pegar (ctrl + v)
win32api.keybd_event(17, 0, 0, 0) # presionar tecla ctrl
win32api.keybd_event(86, 0, 0, 0) # presionar tecla v
win32api.keybd_event(86, 0, win32con.KEYEVENTF_KEYUP, 0) # levantar tecla v
win32api.keybd_event(17, 0, win32con.KEYEVENTF_KEYUP, 0) # 升起按键 ctrl
time.sleep(1)
# 回车(enter)
win32api.keybd_event(13, 0, 0, 0) # 按下按键 enter
win32api.keybd_event(13, 0, win32con.KEYEVENTF_KEYUP, 0) # 升起按键 enter
...

是不是很麻烦,当然,你甚至可以用按键把整个路径输入进去,不过,我想没人愿意这么做的。而且在此过程中你不能随意移动鼠标,不能使用剪贴板,太不稳定了,所以非常不建议你用这种办法。。

3.多文件上传

接下来还有一种情况值得我们考虑,那就是多文件上传。如何上传多个文件,当然我们还是往输入框里输入文件路径,所以唯一要搞清楚的就是多文件上传时,文件路径是怎么写的。

我来告诉你吧,多文件上传就是在文件路径框里用引号括起单个路径,然后用逗号隔开多个路径,就是这么简单,例如:
"D:\a.txt" "D:\b.txt"
但需要注意的是:只有多个文件在同一路径下,才能这样用,否则是会失败的(下面的写法是不可以的):
"C:\a.txt" "D:\b.txt" 

接下里找一个例子试试:

示例网址:http://www.sucaijiayuan.com/api/demo.php?url=/demo/20150128-1

代码:

# -*- coding: utf-8 -*-
from selenium import webdriver
import win32gui
import win32con
import time
dr = webdriver.Firefox()
dr.get('http://www.sucaijiayuan.com/api/demo.php?url=/demo/20150128-1)
dr.switch_to.frame('iframe') # 一定要注意frame
dr.find_element_by_class_name('filePicker').click()
time.sleep(1)
dialog = win32gui.FindWindow('#32770', None)
ComboBoxEx32 = win32gui.FindWindowEx(dialog, 0, 'ComboBoxEx32', None)
ComboBox = win32gui.FindWindowEx(ComboBoxEx32, 0, 'ComboBox', None)
Edit = win32gui.FindWindowEx(ComboBox, 0, 'Edit', None)
button = win32gui.FindWindowEx(dialog, 0, 'Button', None)
# El código es el mismo que en el ejemplo anterior, solo se pasan diferentes parámetros. Si lo desea, puede escribir una función de carga para encapsular la función de carga
win32gui.SendMessage(Edit, win32con.WM_SETTEXT, 0, '"d:\\baidu.py" "d:\\upload.py" "d:\\1.html"')
win32gui.SendMessage(dialog, win32con.WM_COMMAND, 1, button)
print dr.find_element_by_id('status_info').text
dr.quit()

Resultado:

Seleccionar3Ficheros, en total1.17KB。

Por lo tanto, la carga de múltiples archivos no es tan compleja, ni tan simple, la única diferencia es que los parámetros de entrada son diferentes. autoIT también puede lograrlo, si tiene interés, puede intentarlo por su cuenta.

Y podemos descubrir un punto, es que el código de la ventana superior es básicamente igual al del ejemplo anterior, lo que significa que podemos extraer la parte de carga y escribir una función, de modo que cada vez que necesitemos cargar, simplemente llamamos a la función y pasamos los parámetros.

Mira, la carga es realmente fácil de manejar.

Esto es todo el contenido de este artículo, espero que ayude a su aprendizaje y que todos los demás apoyen a la tutorial de grito.

Declaración: El contenido de este artículo se obtiene de la red, es propiedad del autor original, el contenido se contribuye y carga de manera autónoma por los usuarios de Internet, este sitio no posee los derechos de propiedad, no se ha realizado una edición humana y no asume ninguna responsabilidad legal. Si encuentra contenido sospechoso de copyright, le invitamos a enviar un correo electrónico a: notice#oldtoolbag.com (al enviar un correo electrónico, por favor reemplace # con @) para denunciar, y proporcione evidencia relevante. Una vez verificada, este sitio eliminará inmediatamente el contenido sospechoso de infracción.

Te gustará