Python Selenium auf Input klicken?


29.07.2021, 17:55

P.S.: Anstatt "Kassenbon hochladen", müsste es " hochladen" heißen.


30.07.2021, 11:06

Funktioniert bei jemandem das ganze auch nicht, wenn man nur: <input id = "test "type="file"> hat und dann mit driver.get_element_by_id("test").click() zu clicken versucht?

2 Antworten

Vom Fragesteller als hilfreich ausgezeichnet

Zunächst hierzu:

AttributeError: 'list' object has no attribute 'click'

Dieser Fehler ist logisch. Wenn du find_elements_by_xpath verwendest, darfst du auch erwarten, dass eine Ergebnisliste zurückgeliefert wird. Egal, ob diese nun einen Eintrag enthält oder mehrere. Um nun einen Klick auf eines der gefundenen Elemente auszuführen, müsstest du dieses erst aus der Liste holen. Stelle zuvor stets sicher, dass das Element überhaupt existiert. Wolltest du bspw. das zweite Element erhalten, wäre es ratsam, erst zu prüfen, ob es denn zwei Elemente in der Liste gibt:

elements = driver.find_elements_by_xpath("...")

if len(elements) > 1:
  second_element = elements[1]
  # do something ...

Wenn dich prinzipiell nur das erste Vorkommen interessiert, nutze find_element_by_xpath.

Funktioniert bei jemandem das ganze auch nicht, (...)

Ich habe es an deinem speziellen Anwendungsfall einmal getestet (mit ChromeDriver Version 92, um genau zu sein). Die Notwendigkeit für einen XPath-Selektor habe ich nicht gesehen, da das Element schon eindeutig mit einer ID gekennzeichnet ist, die zudem nur einmal auf der Seite vorkommt (wie ich dir ja schon bei deiner anderen Frage schrieb, ist das bei dieser Seite nicht unbedingt selbstverständlich).

Dem Element muss nur der Pfad via send_keys übermittelt werden.

driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://gruenkraft-zufriedenheit.de/")

element = driver.find_element_by_id("receipt")
element.send_keys(r"C:\path\to\some\file.txt")

Nach Ausführung färbt sich der Button auf der Seite grün und gibt über sein Label bekannt, dass ein Upload stattgefunden hat.

Eine Klickaktion auf ein File-Input hingegen funktioniert nicht, da der Browser in diesem Zuge auch die Auswahl eines Dateipfads erwartet. Dieser Prozess (der Dateiauswahldialog) wird allerdings von deinem Betriebssystem gesteuert, nicht vom Webbrowser. Somit besteht auch für Selenium keine Möglichkeit, diesen Dialog händisch zu bedienen, so wie du es als normaler Nutzer tun würdest. Stattdessen wird eine Fehlermeldung erscheinen, die sich über ein invalides / fehlendes Argument (den erwarteten Dateipfad) beschweren wird. Die click-Methode kann dieses nicht liefern. Sinnigerweise gibt es dafür keine Überladung.

Mach's doch einfach per Klassen-Name, oder per ID.

driver.find_element_by_class_name('receipt-button').click()
Woher ich das weiß:Hobby – Programmieren ist mein Hobby & Beruf
Regex20921518 
Fragesteller
 29.07.2021, 18:06

Hab ich schon, aber dann passiert nichts und es kommt die Meldung: "invalid argument".

0
MrAmazing2  29.07.2021, 18:08
@Regex20921518

Versuchs mal mit dem Code aus meiner Antwort. Vlt. hattest du dich einfach verschrieben.

0
MrAmazing2  29.07.2021, 18:09
@Regex20921518

Ist die Fehlermeldung vlt. etwas länger/genauer als 'Invalid Argument'?

Und sicher dass es sich auf genau die Zeile mit meinem Code bezieht?

An meinem Code ist nämlich eigentlich nichts falsch..

0
Regex20921518 
Fragesteller
 29.07.2021, 18:10
@MrAmazing2

 in check_response

  raise exception_class(message, screen, stacktrace)

selenium.common.exceptions.InvalidArgumentException: Message: invalid argument

0
MrAmazing2  29.07.2021, 18:13
@Regex20921518

Das sollte zwar kommen wenn man mehrere Klassen eingibt, also z.B.

find_element_by_class_name("receipt-button w-button")

aber bei einer einzigen Klasse ("receipt-button") eigentlich nicht... Weird.

1
Regex20921518 
Fragesteller
 29.07.2021, 18:15
@MrAmazing2

Hab ich auch schon ausprobiert, geht aber irgendwie nicht. Mir geht es eigentl. ja nur darum, dass das Dateiauswähl Menü sich selbstständig öffnet...

0
MrAmazing2  29.07.2021, 18:16
@Regex20921518

Also bei dem Code-Ausschnitt, den du geschickt hast, macht der Anker (<a>) garnichts, und man müsste auf das input-Element klicken.

0
MrAmazing2  29.07.2021, 18:22
@Regex20921518

Ok, jo, dann hatte ich recht.

Du musst den INPUT anklicken, nicht den Anchor-Tag.

driver.find_element_by_id('receipt').click()
1
Regex20921518 
Fragesteller
 29.07.2021, 22:08
@MrAmazing2

Hab es mit deinem Code ausprobiert ==> invalid argument

Hab jetzt selbst einen kurzen Code mit input typ = file geschrieben und auch da kommt diese Fehlermeldung. Kommt bei dir auch so was, wenn du nur ein inputfeld für files hast plus id und dann die von dir geschr. Codezeile anwendest?

0
MrAmazing2  29.07.2021, 22:19
@Regex20921518

Hab leider kein Selenium und bin auch grad zu Faul das extra zu downloaden etc xD

Kanns mir bei dir mal über Discord anschauen wenn du willst xD

Für WebScraping hab ich immer BeautifulSoup und Requests benutzt

1
Regex20921518 
Fragesteller
 29.07.2021, 22:23
@MrAmazing2

Hab gerade leider kein Discord mehr drauf und meine Internetverbindung spackt auch wieder rum.

1
Regex20921518 
Fragesteller
 29.07.2021, 22:25
@MrAmazing2

Was mich nur wundert ist, dass die click() Methode für so ziemlich jedes Input Feld funktioniert. Sobald ich aber den Typ zu typ="file" umändere, war´s das dann. Komisch.

0
MrAmazing2  29.07.2021, 22:28
@Regex20921518

Dann kann Selenium vermutlich einfach keinen File-Dialog öffnen.

Dann musst du die Datei so hochladen:

driver.find_element_by_id("receipt").send_keys(os.getcwd()+"/deineDatei.png")
1
MrAmazing2  29.07.2021, 22:31
@Regex20921518

Nö, da wird die selbe Lösung vorgeschlagen die ich dir grad gezeigt hab xD

You can try to locate the hidden input and type into it. (-> send_keys)

und

driver.find_element_by_id("IdOfInputTypeFile").send_keys(os.getcwd()+"/image.png")
1
MrAmazing2  29.07.2021, 22:56
@Regex20921518

War das die Lösung?

Klappt's jetzt? :D

Weil dann besser ich meine Antwort aus, für jeden der zukünftig das Problem hat xD

1
Regex20921518 
Fragesteller
 30.07.2021, 11:02
@MrAmazing2

Nope, aber "hoffe" mal, dass Selenium diesen Input Typ einfach noch nicht implementiert bekommen hat...

0