Mit Webdriver zum Element scrollen?

72

Ich lerne noch und beantworte eine meiner Fragen: Hier wurde mir gesagt, dass dies möglicherweise daran liegt, dass das betreffende Element nicht in Sicht ist.

Ich habe die Dokumentation durchgesehen und SO, hier war die relevanteste Antwort: hier

Mit der Klasse "org.openqa.selenium.interactions.Actions" können Sie zu einem Element wechseln:

WebElement element = driver.findElement(By.id("my-id"));
Actions actions = new Actions(driver);
actions.moveToElement(element);
## actions.click();
actions.perform();

Wenn ich versuche, das Obige zu verwenden, um zum Element zu scrollen: Es heißt, WebElement ist nicht definiert.

Ich denke, das liegt daran, dass ich das entsprechende Modul nicht importiert habe. Kann jemand darauf hinweisen, was ich importieren soll?

Bearbeiten: Wie von alecxe hervorgehoben, war dies Java-Code.

Aber in der Zwischenzeit gleich nach dem Versuch, es für einige Zeit herauszufinden. Ich habe die Importmethode für WebElement herausgefunden:

from selenium.webdriver.remote.webelement import WebElement

Könnte jemandem wie mir helfen.

Das Wie ist auch eine gute Lektion, IMO:

Ging zu: Dokumentation Die

class selenium.webdriver.remote.webelement.WebElement(parent, id_, w3c=False)

Muss in das oben erwähnte Befehlsformular getrennt werden.

Sid
quelle

Antworten:

130

Sie versuchen, Java-Code mit Python auszuführen. In Python / Selen org.openqa.selenium.interactions.Actionswerden die in der ActionChainsKlasse wiedergegeben :

from selenium.webdriver.common.action_chains import ActionChains

element = driver.find_element_by_id("my-id")

actions = ActionChains(driver)
actions.move_to_element(element).perform()

Sie können auch über Folgendes in die Ansicht "scrollen" scrollIntoView():

driver.execute_script("arguments[0].scrollIntoView();", element)

Wenn Sie an den Unterschieden interessiert sind:

Alecxe
quelle
Ah ... da war ich 3 Stunden lang und habe jede Methode ausprobiert, die ich auf SO und der Dokumentation gefunden habe. Ich habe die erste Lösung ausprobiert, muss sie aber irgendwie durcheinander gebracht haben. Ich werde das ScrollIntoView Vs moveToElement lesen. Nur eine kurze Frage: Ich muss die gleichen Schritte 100 Mal forausführen. Ich denke darüber nach, eine Schleife zu verwenden. Wäre das ein guter Ansatz?
Sid
@Sid schwer zu sagen. In bestimmten Fällen können Sie die Aktionen einfach in einer Schleife verketten und dann einmal nach der Schleife ausführen. Dies hängt jedoch von einem Anwendungsfall ab. Prüfen Sie, ob es sinnvoll ist, ein separates SO-Thema dafür zu erstellen, wenn Hilfe benötigt wird. Vielen Dank.
Alecxe
wird move_to_element(ele).perform()einfach zu einem Element gescrollt, auch wenn das Element gerade nicht angezeigt wird?
Oldboy
1
@alecxe Ich verstehe nicht, wie das funktioniert (bei meinem Projekt nicht), denn wie kann Selen das Objekt finden, zu dem gescrollt werden soll, wenn das Objekt nicht sichtbar ist? Meins kann das Element, zu dem es scrollen soll, nicht finden.
Jeepers Mcface
2
Als ich move_to aufgerufen habe, wie Sie vorgeschlagen haben, habe ich selenium.common.exceptions.MoveTargetOutOfBoundsException erhalten: Nachricht: (164, 1297) liegt außerhalb der Grenzen der Breite (1366) und Höhe (694) des Ansichtsfensters. Ich bin dankbar für Ihre Antwort und denke, dass dies der richtige Weg ist (und ich habe aus Ihrer Antwort auch etwas über ActionChains gelernt), aber es sieht so aus, als müsste es ein wenig verbessert werden. Thanks1
dotz
53

Es ist keine direkte Antwort auf eine Frage (es geht nicht darum Actions), aber es ermöglicht Ihnen auch, einfach zum gewünschten Element zu scrollen:

element = driver.find_element_by_id('some_id')
element.location_once_scrolled_into_view

Dies beabsichtigt tatsächlich, Ihnen die Koordinaten ( x, y) des Elements auf der Seite zurückzugeben, aber auch nach rechts zum Zielelement zu scrollen

Andersson
quelle
Danke @Andersson Ich habe versucht, den Weg dazu zu finden, da Sie darauf hingewiesen haben, dass dies das Problem bei der anderen Frage sein könnte. :)
Sid
2
Zuerst habe ich ()hinterher angehängt und Fehler '' dict 'Objekt ist nicht aufrufbar', ich habe überprüft, ob der Elementtyp ist WebElement. dann habe ich entfernt () und gearbeitet. Ist das nicht eine Methode? Ich meine, warum keine ()Notwendigkeit?
Lei Yang
1
@LeiYang, da location_once_scrolled_into_view eine Python- Eigenschaft ist . Eigenschaften akzeptiert keine Argumente (außer Objektinstanz -self) und sollte ohne Klammern aufgerufen werden
Andersson
1
@Andersson .move_to_element () hat bei mir nicht funktioniert (ich habe die Antwort von alecxe kommentiert), aber Ihre Lösung hat funktioniert. VIELEN DANK!
Dotz
@LeiYang Hier ist der Quellcode über location_once_scrolled_into_view, um zu erklären, warum ()nicht benötigt: selenium / webelement.py bei d3b6ad006bd7dbee59f8539d81cee4f06bd81d64 · SeleniumHQ /
selenium
3

Zusätzlich zu move_to_element()und scrollIntoView()ich wollte den folgenden Code stellen , die Versuche zu zentrieren das Element in der Ansicht:

desired_y = (element.size['height'] / 2) + element.location['y']
window_h = driver.execute_script('return window.innerHeight')
window_y = driver.execute_script('return window.pageYOffset')
current_y = (window_h / 2) + window_y
scroll_y_by = desired_y - current_y

driver.execute_script("window.scrollBy(0, arguments[0]);", scroll_y_by)
Neil C. Obremski
quelle
Vielen Dank für Ihre Lösung, andere Möglichkeiten ausprobiert, aber das Element war nicht anklickbar. Einige Zeit nicht genug Bildlauf, Element war unter "Chat-Box" unten, andere Code zu viel Bildlauf-Element war oben unten. Menü
Wonka
0

Es gibt eine weitere Option, um die Seite zum gewünschten Element zu scrollen, wenn das Element ein "id"Attribut hat

Wenn Sie zur Seite navigieren und mit zum Element nach unten scrollen möchten @id, können Sie dies automatisch durch Hinzufügen #element_idzur URL tun ...

Beispiel

Angenommen, wir müssen zur Dokumentation zu Selenium Waits navigieren und die Seite nach unten zum Abschnitt "Implicit Wait" scrollen. Wir können es tun

driver.get('https://selenium-python.readthedocs.io/waits.html')

und Code zum Scrollen hinzufügen ... ODER verwenden

driver.get('https://selenium-python.readthedocs.io/waits.html#implicit-waits')

um zur Seite zu navigieren UND Seite automatisch zum Element mit id="implicit-waits"( <div class="section" id="implicit-waits">...</div>) zu scrollen

Andersson
quelle
0

Sie können mit Javascript über die execute_javascriptMethode zum Element scrollen . Hier ist zum Beispiel, wie ich es mit SeleniumLibrary auf Robot Framework mache:

web_element = self.selib.find_element(locator)
self.selib.execute_javascript(
    "ARGUMENTS",
    web_element,
    "JAVASCRIPT",
    'arguments[0].scrollIntoView({behavior: "instant", block: "start", inline: "start"});'
)
Antony Fuentes Artavia
quelle
0

Dies kann mit driver.execute_script () erfolgen: -

driver.execute_script("document.getElementById('myelementid').scrollIntoView();")
ePandit
quelle
0

Beispiel:

driver.execute_script("arguments[0].scrollIntoView();", driver.find_element_by_css_selector(.your_css_selector))

Dieser funktioniert bei mir immer für jede Art von Selektoren. Es gibt auch die Actions-Klasse, aber für diesen Fall ist sie nicht so zuverlässig.

vitaliis
quelle