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

Обзор методов загрузки файлов в Python selenium

Загрузка файлов - это проблема, с которой все UI-автоматические тесты сталкиваются, сегодня блогер делится своим опытом в этом вопросе, надеясь помочь всем, кто застрял в проблеме загрузки файлов с selenium.

Сначала мы должны отличить типы кнопок загрузки, в общем, они делятся на два типа, один из которых - это input-окно, а другой более сложный, реализованный с помощью js, flash и т.д., тег не input

Мы анализируем эти два:

1. Input-тег

Как известно, input-тег можно directly send_keys, это не исключение, посмотрим на пример кода:

Пример网址: 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') # check value
driver.quit()

Результат:

baidu.py

很明显,для input-загрузки simplest решение - это directly send_keys.

2. Ненадлежащие input-типу загрузки

В следующий раз难度 будет увеличен, что делать с загрузками, которые не реализованы с помощью input-окончаний? Этот тип загрузки очень разнообразен, есть те, которые используют a-теги, div, button, object, мы не можем напрямую обработать эти загрузки на веб-странице, единственный способ - открыть диалоговое окно OS, чтобы обработать диалоговое окно.

Проблема снова arose, уровень OS弹出窗口, уже не может быть решен selenium, что делать? очень просто, использовать операции уровня OS для обработки, до этого мы уже нашли способ решения проблемы.

В общем, есть следующие несколько решений:
 1.autoIT, используя внешние ресурсы, мы вызываем созданные им файлы au3 или exe.
 2. Библиотека Python pywin32, распознает диалоговые окна, и таким образом выполняет операции
 3. Библиотека SendKeys
 4.keybd_event, как и 3, но это имитация клавиатурных действий, ctrl+a, ctrl+c, ctrl+v... 

В настоящее время я знаю только четыре из них, если у вас есть другие методы, пожалуйста, оставьте комментарий, чтобы я мог узнать.

Мы будем рассматривать их по порядку:

1. autoIT

О методах загрузки autoIT и параметризации я уже говорил в другой статье, пожалуйста, смотрите selenium autoit command line parameters. Здесь я не буду повторяться.

2.win32gui

Не будем говорить больше, давайте начнем с кода:

Пример网址: 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'Файл: Загрузка') # Диалоговое окно
ComboBoxEx32 = win32gui.FindWindowEx(dialog, 0, 'ComboBoxEx32', None) 
ComboBox = win32gui.FindWindowEx(ComboBoxEx32, 0, 'ComboBox', None)
Edit = win32gui.FindWindowEx(ComboBox, 0, 'Edit', None) # Ищем объекты по порядку, пока не найдем хендлер объекта ввода Edit
button = win32gui.FindWindowEx(dialog, 0, 'Button', None) # Определить кнопку Button
win32gui.SendMessage(Edit, win32con.WM_SETTEXT, None, 'd:\\baidu.py') # Ввести абсолютный адрес в поле ввода
win32gui.SendMessage(dialog, win32con.WM_COMMAND, 1, button) # Нажать на кнопку button
print upload.get_attribute('value')
dr.quit()

Результат:

baidu.py

Здесь вам потребуется очень важная маленькая утилита: Spy++, вы можете найти много информации о нем в Бaidu,当然 вы также можете использовать инструменты, встроенные в autoIT, но они не так хороши, советую загрузить этот.

Кроме того, вам нужно установить библиотеку pywin32, вы можете посетитьЗдесьНайдите библиотеку, соответствующую вашей версии Python, обратите внимание, что 32-битный или 64-битный должен соответствовать вашей установленной версии Python.

После установки вы можете увидеть документацию PyWin32 в папке [Start Menu > Python] под названием [Python for Windows Documentation], где вы можете найти соответствующие метод API.

Просто кратко介绍一下几个用到的:

win32gui.FindWindow(lpClassName=None, lpWindowName=None):
 •Начать искать окно, которое соответствует условиям с[top-уровня окна], и вернуть его хендлер.
 •lpClassName: имя класса, которое можно увидеть в Spy++.
 •lpWindowName: имя окна, которое можно увидеть в строке заголовка.
 •Пример кода, который мы используем для поиска окна загрузки, вы можете использовать только один из них, для定位 по classname может быть легко干扰其他元素,для定位 по windowname может быть нестабильным, различные диалоговые окна загрузки могут иметь различное window_name, как определить зависит от вашей ситуации. 

win32gui.FindWindowEx(hwndParent=0, hwndChildAfter=0, lpszClass=None, lpszWindow=None)
 • Поиск окна, которое соответствует классу и имени окна, и возвращается обработчик этого окна. Если не найдено, то возвращается 0.
 • hwndParent: если не равно 0, то будут搜索 hwndParent окна подокна.
 • hwndChildAfter: если не равно 0, то по порядку от hwndChildAfter начнётся поиск подокна,否则 от первого подокна.
 • lpClassName: строковый тип, это имя класса окна, это можно найти в Spy++.
 • lpWindowName: строковый тип, это имя окна, то, что вы видите на заголовке окна.
 • В примере кода мы используем его для построчного поиска поля ввода и кнопки "ОК" 

win32gui.SendMessage(hWnd, Msg, wParam, lParam)
 • hWnd: целочисленный, обработчик окна, которое принимает сообщение
 • Msg: целочисленный, сообщение, которое нужно отправить, все эти сообщения предварительно определены в Windows, см. Системные определённые сообщения (System-Defined Messages)
 • wParam: целочисленный, параметр wParam сообщения
 • lParam: целочисленный, параметр lParam сообщения
 • В примере кода мы используем его для ввода адреса файла в поле ввода и нажатия на кнопку "ОК" 

Что касается модуля win32api и других методов, здесь не будет дальнейшего описания, если хотите узнать больше, ищите в Бaidu или смотрите документацию pywin32.

3.SendKeys

Сначала нужно установить библиотеку SendKeys, это можно сделать с помощью pip

pip install SendKeys 

Пример кода:

Пример网址: 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') # Отправка адреса файла
SendKeys.SendKeys("{ENTER}") # Отправить клавишу ввода
print upload.get_attribute('value')
dr.quit()

Результат:

baidu.py

С помощью библиотеки SendKeys можно напрямую вводить информацию в фокус, но следует учитывать, что при открытии окна нужно немного подождать, иначе может не получиться ввести первый символ (или вы можете добавить无用ной символ перед адресом). Однако я считаю, что этот метод нестабилен и не рекомендуется.

4.keybd_event

win32api предоставляет метод keybd_event() для имитации клавиш, но этот метод сложен и не стабилен, поэтому его не рекомендуется использовать. Ниже приведен пример части кода. Если вы хотите изучить это, пожалуйста, найдите информацию в Интернете.

# Найти один input框, ввести адрес файла, который нужно загрузить, и скопировать его в буфер обмена 
video.send_keys('C:\\Users\\Administrator\\Pictures\\04b20919fc78baf41fc993fd8ee2c5c9.jpg')
video.send_keys(Keys.CONTROL, 'a') # selenium send_keys (ctrl+a)
video.send_keys(Keys.CONTROL, 'x') # (ctrl+x)
driver.find_element_by_id('uploadImage').click() # Нажать кнопку загрузки, открыть окно загрузки
# Вставка (ctrl + v)
win32api.keybd_event(17, 0, 0, 0) # Нажатие клавиши ctrl
win32api.keybd_event(86, 0, 0, 0) # Нажатие клавиши v
win32api.keybd_event(86, 0, win32con.KEYEVENTF_KEYUP, 0) # Поднимание клавиши 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)
# Код такой же, как в предыдущем примере, только传入 разные параметры, если хотите, можно написать функцию для загрузки и упаковать функциональность загрузки
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()

Результат:

Выбрано 3 файла, всего 1.17KB.

Таким образом, загрузка нескольких файлов не так сложна и не так проста, единственное различие - это различие в параметрах ввода. autoIT также может это сделать, если вы有兴趣, попробуйте сами.

И мы можем заметить, что код в этом окне примерно такой же, как в предыдущем примере, что означает, что мы можем вытащить часть загрузки и написать функцию, чтобы при каждом загрузке можно было просто вызывать функцию и передавать параметры.

Смотрите, загрузка на самом деле легко решается.

Вот и все, что есть в этой статье, надеюсь, это поможет вам в изучении, также希望大家多多支持呐喊教程。

Заявление: содержимое этой статьи взято из Интернета, авторские права принадлежат соответствующему автору, содержимое предоставлено пользователями Интернета в добровольном порядке, сайт не обладает правами собственности, не производилось редактирование, также не несет ответственности за связанные с этим юридические последствия. Если вы обнаружите подозрительное нарушение авторских прав, пожалуйста, отправьте письмо по адресу: notice#oldtoolbag.com (во время отправки письма замените # на @) для подачи жалобы,并提供 соответствующие доказательства. При подтверждении факта нарушения авторских прав сайт немедленно удаляет подозрительное контент.

Основной учебник
Рекомендуется для вас