English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Datei-Upload ist ein lästiges Problem, das alle UI-Automatisierungstests angehen müssen, heute teilt der Blogger hier seine Erfahrungen im Umgang mit Datei-Uploads mit, hoffentlich kann dies den vielen Seleniumern, die von Datei-Uploads betroffen sind, helfen.
Zunächst müssen wir die Arten der Upload-Schaltflächen unterscheiden, grob gesagt gibt es zwei Arten, eine ist das Input-Feld und die andere ist komplexer, sie wird durch js, flash und andere Methoden realisiert, der Tag ist nicht input
Wir analysieren beide separately:
1.input-Tag
Wie alle wissen, kann das input-Tag direkt send_keys verwenden, hier ist das auch der Fall, sehen wir uns das Beispielcode an:
Beispiel-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') # 检查值 driver.quit()
Ergebnis:
baidu.py
很明显,对于input上传,直接send_keys是最简单的解决方案。
2.非input型上传
接下来难度要升级了,对于那些不是input框实现的上传怎么办,这种上传千奇百怪,有用a标签的,有用div的,有用button的,有用object的,我们没有办法通过直接在网页上处理掉这些上传,唯一的办法就是打开OS弹框,去处理弹框。
问题又来了,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命令行参数。这里不再赘述。
2.win32gui
不多说废话,先上代码:
Beispiel-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'文件上传') # 对话框 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, 1button) # 按button print upload.get_attribute('value') dr.quit()
Ergebnis:
baidu.py
在这里你需要一个非常重要的小工具:Spy++百度一下有很多,当然你也可以使用autoIT自带的工具,不过没有这个好用,建议去下一个吧。
und, Sie müssen pywin installieren32Bibliothek, können Sie zuhierden Bibliothek, die für Ihre Python-Version zutreffend ist, beachten Sie32Kompilationsversion noch64Kompilationsversion muss mit der installierten Python-Version übereinstimmen.
Nach der Installation finden Sie in der Schaltfläche „Startmenü Python-Ordner“ PyWin32Dokumentation 【Python for Windows Documentation】,dort können Sie die entsprechenden Methoden API finden.
Einführung in einige verwendete:
win32gui.FindWindow(lpClassName=None, lpWindowName=None):
•Suchen Sie von der obersten Fensterebene beginnend nach Fenstern, die den Suchkriterien entsprechen, und geben Sie den Fenstersatzhandle dieses Fensters zurück.
•lpClassName: Klassennamen, in Spy++. zu sehen
•lpWindowName: Fenstertitel, der Name, den Sie auf der Titelleiste sehen können
•In Beispielscode verwenden wir es, um das Uploadfenster zu finden, Sie können eines davon verwenden, classname ist leicht durch andere Dinge gestört, windowname ist instabil, verschiedene Upload-Dialoge können unterschiedliche window_name haben, wie Sie定位abhängt von Ihrer Situation.
win32gui.FindWindowEx(hwndParent=0, hwndChildAfter=0, lpszClass=None, lpszWindow=None)
•Suchen Sie nach Fenstern, deren Klassennamen und Fenstertitel übereinstimmen, und geben Sie den Fenstersatzhandle dieses Fensters zurück. Wenn nichts gefunden wird, geben Sie 0 zurück.
•hwndParent: Wenn nicht 0, suchen Sie nach Untefenstern des Fensters hwndParent
•hwndChildAfter: Wenn nicht 0, suchen Sie nach Untefenstern gemäß z-index von hwndChildAfter beginnend nach hinten suchen, andernfalls beginnen Sie mit dem ersten Untefenster
•lpClassName: Zeiger auf Zeichen, ist der Fenstertitel, dieser kann in Spy++. gefunden.
•lpWindowName: Zeiger auf Zeichen, ist der Fenstertitel, also der Titel, den Sie auf der Titelleiste sehen können.
•In Beispielscode verwenden wir es, um das Eingabefeld und die Schaltfläche 'OK' sukzessive zu finden
win32gui.SendMessage(hWnd, Msg, wParam, lParam)
•hWnd: Ganzzahl, der Fenstersatzhandle des Fensters, das die Nachricht empfängt
•Msg: Ganzzahl, die zu sendende Nachricht, alle diese Nachrichten sind von Windows voraufgelegt und können in den Systemdefinitionsnachrichten (System-Definierte Nachrichten)
•wParam: Ganzzahl, der wParam-Parameter der Nachricht
•lParam: Ganzzahl, der lParam-Parameter der Nachricht
•In Beispiels代码, verwenden wir es, um die Dateiadresse in das Eingabefeld einzugeben und auf die Schaltfläche 'OK' zu klicken
Betrifft win32api-Modul und andere Methoden werden hier nicht weiter beschrieben. Wenn Sie mehr darüber erfahren möchten, suchen Sie selbst im Internet nach Informationen oder schauen Sie in pywin nach.32Dokumentation.
3.SendKeys
Zunächst muss die SendKeys-Bibliothek installiert werden. Dies kann mit pip installiert werden.
pip install SendKeys
Code-Beispiel:
Beispiel-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') # Dateiadresse senden SendKeys.SendKeys("{ENTER}") # Enter-Taste senden print upload.get_attribute('value') dr.quit()
Ergebnis:
baidu.py
Mit dem SendKeys-Bibliothek kann man direkt Informationen in den Fokus eingeben. Es sollte jedoch auf eine geringfügige Wartezeit beim Öffnen des Fensters geachtet werden, da andernfalls der erste Buchstabe möglicherweise nicht gesendet wird (oder Sie können einen nutzlosen Zeichen vor der Adresse hinzufügen). Ich finde diese Methode jedoch nicht stabil und empfehle sie nicht.
4.keybd_event
win32api bietet eine keybd_event() Methode an, um Tastendrücke zu simulieren, aber dieser Methode ist etwas umständlich und nicht stabil, daher wird sie nicht empfohlen. Unten sind einige Code-Beispiele gegeben. Wenn Sie das studieren möchten, suchen Sie selbst im Internet nach Informationen.
# Finden Sie einen Input-Bereich, geben Sie die Adresse des Dateiupload zu, kopieren Sie sie in die Zwischenablage 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() # aufdecken Upload-Button, Upload-Fenster öffnen # Einfügen (ctrl + v) win32api.keybd_event(17, 0, 0, 0) # Taste ctrl drücken win32api.keybd_event(86, 0, 0, 0) # Taste v drücken win32api.keybd_event(86, 0, win32con.KEYEVENTF_KEYUP, 0) # aufheben Taste 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) # Der Code ist gleich wie im obigen Beispiel, nur die übergebenen Parameter sind unterschiedlich. Wenn Sie möchten, können Sie eine Upload-Funktion schreiben, um die Upload-Funktion zu verpacken 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()
Ergebnis:
ausgewählt3Datei, insgesamt1.17KB.
Also ist das Hochladen mehrerer Dateien nicht so kompliziert und auch sehr einfach, der einzige Unterschied ist, dass die übergebenen Parameter unterschiedlich sind. autoIT kann dies ebenfalls erreichen, wenn Sie Interesse haben, können Sie es selbst ausprobieren.
Und wir können feststellen, dass der Code in diesem Fenster im Grunde dem im vorherigen Beispiel gleich ist, was bedeutet, dass wir den Upload-Teil extrahieren und eine Funktion schreiben können, um sie jedes Mal aufzurufen, wenn eine Übertragung erforderlich ist, indem einfach Parameter übergeben werden.
Sieh dir an, das Hochladen ist eigentlich sehr einfach zu handhaben.
Das ist der gesamte Inhalt dieses Artikels. Wir hoffen, dass er Ihnen bei Ihrem Lernen hilft und wir hoffen, dass Sie die呐喊教程 mehr unterstützen.
Erklärung: Der Inhalt dieses Artikels wurde aus dem Internet übernommen und gehört dem jeweiligen Urheber. Der Inhalt wurde von Internetnutzern freiwillig bereitgestellt und hochgeladen. Diese Website besitzt keine Eigentumsrechte und hat den Inhalt nicht manuell bearbeitet. Sie übernimmt auch keine rechtlichen Verantwortlichkeiten. Wenn Sie verdächtige urheberrechtliche Inhalte finden, freuen wir uns über eine E-Mail an: notice#oldtoolbag.com (Bitte ersetzen Sie # durch @, wenn Sie eine Meldung senden, und geben Sie relevante Beweise an. Sobald nachgewiesen wird, dass die Inhalte urheberrechtlich geschützt sind, wird diese Website die fraglichen Inhalte sofort löschen.)