셀레늄을 사용하여 요소를보기로 스크롤


207

XPath로 식별 된 특정 요소가 브라우저를 볼 수 있도록 Selenium 1.x 또는 2.x에서 브라우저 창을 스크롤하는 방법이 있습니까? Selenium에는 초점 방법이 있지만 FireFox에서는 실제로보기를 스크롤하지 않는 것 같습니다. 누구 든지이 작업을 수행하는 방법에 대한 제안이 있습니까?

내가 필요한 이유는 페이지에서 요소의 클릭을 테스트하고 있기 때문입니다. 불행히도 요소가 보이지 않으면 이벤트가 작동하지 않는 것 같습니다. 요소를 클릭 할 때 발생하는 코드를 제어 할 수 없으므로 디버깅하거나 수정할 수 없으므로 가장 쉬운 해결책은 항목을보기로 스크롤하는 것입니다.


이 해키 하나를 시도 할 수 있습니다 아무것도 당신을 위해 작동하지 않는 경우 : stackoverflow.com/a/53771434/7093031
— YB의 원인이

답변:


214

스크롤과 관련하여 많은 것을 시도했지만 아래 코드는 더 나은 결과를 제공했습니다.

요소가 표시 될 때까지 스크롤됩니다.

WebElement element = driver.findElement(By.id("id_of_element"));
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", element);
Thread.sleep(500); 

//do anything you want with the element

6
이것은 position: fixed페이지에 요소가 있고 Selenium이 클릭하려는 요소를 가리는 경우에 대한 깔끔한 솔루션입니다 . 종종 고정 요소가 맨 아래로 scrollIntoView(true)이동 하므로 설정 하면 뷰포트의 맨 위로 멋지게 이동합니다.
— Mandible79

3
최신 버전의 셀레늄 (2.53)을 기반으로하는이 솔루션은 이제 훌륭한 도우미 솔루션입니다. 셀레늄이 항상 요소를 화면으로 스크롤하지는 않으므로 확실히 유용합니다.
— Zoidberg

20
으로 이동 true하는 scrollIntoView당신이 스크롤하고있는 객체가 현재있는 곳 아래에 있다면 false당신은 스크롤하고있는 객체가 현재 어디에 이상이면. 나는 그것을 알아내는 데 어려움을 겪었다.
— 큰 돈

2
왜 스레드 수면이 필요합니까? executeScript는 동 기적이어야합니다
— riccardo.tasso

1
@ riccardo.tasso 수면이 알려지지 않은 대상 앱을 처리하기 위해 구현되었을 수 있습니다. 동적 스크롤 또는 스크롤 후 페이지의 다음 비트를로드하는 단일 페이지 앱이있는 경우 다른 가능성이 있습니다. 경험에 비추어 볼 때 Selenium은 Javascript가 완료 할 수있는 것보다 자동 작업이 더 빨리 발생하여 불완전한 데이터 모델을 통과했기 때문에 회사 사이트를 자주 중단했습니다. 어떤 곳에서는 버그로 간주 할 수 있지만 "어떤 사람도 그러한 시나리오를 호출 할 수 없으므로 실제 버그는 아닙니다"라고 들었습니다. C'est la vie.
— Solonotix

157

org.openqa.selenium.interactions.Actions클래스를 사용하여 요소로 이동할 수 있습니다 .

자바:

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

파이썬 :

from selenium.webdriver.common.action_chains import ActionChains
ActionChains(driver).move_to_element(driver.sl.find_element_by_id('my-id')).perform()

7
WebElement가 View Port에없는 경우이 기능이 작동합니까?
— virusrocks

9
@Dominik : Selenium은 어떻게 마우스를 화면 밖에있는 요소로 옮기나요? 분명히 요소를 먼저 스크롤 한 다음 마우스를 요소로 이동해야합니다. 나는 그것을 테스트했다. 이 코드는 Firefox Webdriver 2.48에서 작동하지만 버그가 있습니다. 페이지에 iframe이 있으면 element.LocationOnScreenOnceScrolledIntoView가 올바르게 스크롤되는 동안 iframe에서 스크롤이 올바르게 작동하지 않습니다. (문서에 따르면이 명령은 위치 만 반환한다고 스크롤하지만 스크롤됩니다!)
— Elmue

7
seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/…에 있는 문서는 이제 명확하게 "마우스를 요소의 중앙으로 이동합니다. 요소가 스크롤되어 위치가 계산됩니다. getBoundingClientRect. "
— George Pantazes

5
위의 코드는 "공식적인 방법"입니다. Java Selenium은 요소를 뷰포트로 스크롤하기를 원하지만 많은 일을 시도한 후 JS 구현이 더 안정적으로 작동하는 것처럼 보입니다. 특히이 방법 .
— Kenji Miwa

2
나를 위해 작동하지 않았다 :-| 사용 stackoverflow.com/a/23902068/661414을 대신.
— Leukipp

28
JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("javascript:window.scrollBy(250,350)");

시도해 볼 수 있습니다.


1
감사. Selenium의 자동 스크롤로 인해 다른 요소로 인해 클릭해야 할 요소가 가려지는 경우이 방법을 사용해야했습니다. 임의의 양을 스크롤하여 요소를 가리지 않고 뷰포트에 요소를 표시 할 수있었습니다.
— Daniel Richnak

이것은 FIrefox, Chrome 및 IE에서만 작동합니다.이 방법을 지원하지 않습니다
— virusrocks

이것이 js.ExecuteScript("arguments[0].scrollIntoView(true);" + "window.scrollBy(0,-100);", e);IE 및 Firefox 및 js.ExecuteScript("arguments[0].scrollIntoViewIfNeeded(true);", e);Chrome에 사용 하는 이유 입니다. 단순한.
— IamBatman

((JavascriptExecutor) driver).executeScript("javascript:window.scrollBy(0,250)");이것은 Chrome에서 작동했습니다. 그리고 실제로 저에게 효과적이었습니다. 첫 번째 논평자와 같은 상황에서 클릭해야 할 요소를 계속 가리는 고정 요소가 맨 아래에있었습니다.
— 은


15

Selenium 웹 드라이버를 사용하여 Firefox 창에서 스크롤하려면 Java 코드에서 JavaScript를 사용하는 방법 중 하나입니다. 웹 페이지 아래로 스크롤하는 JavaScript 코드는 다음과 같습니다.

JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("window.scrollTo(0, Math.max(document.documentElement.scrollHeight, document.body.scrollHeight, document.documentElement.clientHeight));");

10

모든 요소를 ​​대상으로 하고 키 (또는 위 / 왼쪽 / 오른쪽)를 보내는 것도 효과가있는 것 같습니다. 나는 이것이 약간의 해킹이라는 것을 알고 있지만 스크롤링 문제를 해결하기 위해 JavaScript를 사용하려는 아이디어는 아닙니다.

예를 들면 다음과 같습니다.

WebElement.sendKeys(Keys.DOWN);

이것은 js를 사용하는 것보다 해킹이 아니며 실제로 가장 간단한 것입니다. 클릭이 요소를보기로 스크롤하려고하지만 실제로 만들지 않는 IE의 문제는 주로 발견했습니다. 적절한 try / catch / loop 시나리오로 수행하면 {PGUP}을 사용하여 솔루션을 우아하게 사용할 수 있습니다.
— jibbs

당신은 내 하루를 구했다! 감사합니다
— Jesko R.

필자의 경우 페이지 다운은 효과가있었습니다. 이것은 좋은 해킹입니다 (vs 모든 JS 해킹).
— akostadinov

감사합니다 @DevDave! C #과 동일 :var elem = driver.FindElement(By.Id("element_id")); elem.SendKeys(Keys.PageDown);
— Watth

9
webElement = driver.findElement(By.xpath("bla-bla-bla"));
((JavascriptExecutor)driver).executeScript("arguments[0].scrollIntoView();", webElement);

더 많은 예를 보려면 여기로 이동하십시오 . 모두 러시아어로되어 있지만 Java 코드는 이문화입니다 :)


이 솔루션에 왜 -1이 있는지 이해할 수 있습니까?
— josephnvu

Firefox에서만 작동하기 때문입니다. 다른 브라우저는이 방법을 지원하지 않습니다.
— Wayne Allen

위에서 언급 한 문서를 러시아어로 번역 해야하는 사람이 있으면 기꺼이 도와 드리겠습니다.
— monkrus 2016 년

8

Selenium에서는 JavaScript executor의 도움을 받아 요소로 스크롤하거나 페이지를 스크롤해야합니다.

je.executeScript("arguments[0].scrollIntoView(true);", element);

위의 진술에서 element 에는 스크롤해야 할 정확한 요소가 있습니다. 위의 코드를 시도해 보았습니다.

나는 이것에 대한 완전한 게시물과 비디오를 가지고있다 :

http://learn-automation.com/how-to-scroll-into-view-in-selenium-webdriver/


@Mukesh otwani 위 코드는 아래로 스크롤되지만 abt는 정의 된 픽셀을 사용하지 않고 위로 스크롤합니다.
— khan

6

이 코드 스 니펫을 사용하여 스크롤 할 수 있습니다.

씨#

var element = Driver.FindElement(By.Id("element-id"));
Actions actions = new Actions(Driver);
actions.MoveToElement(element).Perform();

거기 있어요


6

이것은 나를 위해 일했다 :

IWebElement element = driver.FindElements(getApplicationObject(currentObjectName, currentObjectType, currentObjectUniqueId))[0];
 ((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].scrollIntoView(true);", element);

5

Selenium 2는 요소로 스크롤 한 다음 클릭합니다. Selenium 2는 요소가 보이지 않는다고 생각하지 않으면 요소와 상호 작용하지 않기 때문입니다.

요소로 스크롤하면 암시 적으로 발생하므로 항목을 찾아서 작업하면됩니다.


19
이것이 어떻게 질문에 대한 답입니까?
— reinierpost

57
나를 위해 그런 식으로 작동하지 않는 것 같습니다. 보이지 않는 요소에 대해 '요소를 클릭 할 수 없음'오류가 발생합니다
— DevDave

5
@DevDave 내 경우를 제외하고는 셀레늄이 요소에 대해 클릭 동작을 수행하지 않으며 예외는 없습니다. 나는 전에 문제가 없었으며 그 원인을 알지 못했습니다.
— Zeinab Abbasimazar

5
암시 적 스크롤은 브라우저마다 다릅니다. 팝업 메뉴의 한 페이지 아래에 요소 테스트가 있습니다. Ruby gem selenium_webdriver 2.43을 사용하면 크롬 브라우저 37 (및 Internet Explorer)이 메뉴 항목을 실제로 스크롤하여 클릭한다고 생각합니다. 그러나 Firefox 32는 전혀 스크롤되지 않는데 "요소가 현재 보이지 않으므로 상호 작용할 수 없습니다"라는 메시지가 표시되지 않습니다.
— skierpage

9
이 답변은 잘못되었습니다. Selenium 2.0의 사양에 따르면 WebElement.click()요소를 클릭하려면 요소를 볼 수 있어야합니다. 당신을 위해 스크롤되지 않습니다.
— 길리

5

드라이버를 사용하여 pagedown또는 키와 같은 키를 보내 downarrow요소를 볼 수 있습니다. 너무 간단한 해결책이므로 모든 경우에 적용 할 수는 없습니다.


1
이것은 말도 안됩니다. 큰 페이지에 수십 페이지를 아래로 보내야 할 수도 있습니다. 느리고 신뢰할 수 없습니다.
— Elmue

2
예. 나는 동의한다. 그러나 나는 "모든 경우에 해당되지는 않는다"고 말 하였다
— Ganesh S

element볼 수있는 페이지에서 알려진 것을 찾고 PageDown을 보내는 element.SendKeys(Keys.PageDown);것이 저에게 효과적 이었습니다.
— Gokul

Alt 키를 사용하여 페이지를 스크롤하지 않고 try / except (Python) 절을 사용하여 일부 요소에 키를 보내려고 할 때 발생할 수있는 오류를 처리하는 것이 좋습니다.
— Alex K.

4

내 경험상 Selenium Webdriver는 페이지에 스크롤 가능한 섹션이 둘 이상있을 때 클릭 할 때 요소로 자동 스크롤하지 않습니다 (이는 일반적입니다).

Ruby를 사용하고 있으며 AUT의 경우 클릭 방식을 다음과 같이 원숭이 패치해야했습니다.

class Element

      #
      # Alias the original click method to use later on
      #
      alias_method :base_click, :click

      # Override the base click method to scroll into view if the element is not visible
      # and then retry click
      #
      def click
        begin
          base_click
        rescue Selenium::WebDriver::Error::ElementNotVisibleError
          location_once_scrolled_into_view
          base_click
        end
      end

'location_once_scrolled_into_view'메소드는 WebElement 클래스의 기존 메소드입니다.

루비를 사용하지 않을 수도 있지만 아이디어가 필요합니다.


에서 위의 내용을 선언했으며 그냥 대신 module Capybara :: module Node호출해야했습니다 . 또한 Firefox 44.0.2에서 자주 사용되는 구조했습니다. 그러나이 솔루션은 충분히 융통성이 없으며 궁극적으로 수락 테스트 자체에 전화를 걸고 즉시 필요한 곳을 찾습니다 . native.location_once_scrolled_into_viewlocation_once_scrolled_into_view::Selenium::WebDriver::Error::UnknownError<Element>.native.location_once_scrolled_into_viewpage.execute_script('window.scrollByPages(-1)')
— Al Chou

Watir에는 Element#scroll_into_viewSelenium 's에 위임 하는 방법 이 location_once_scrolled_into_view있습니다. 그러나 둘 다 Seleniums 기본 동작과 다르지 않으므로 오버플로 요소는 여전히 클릭하려고하는 모든 것을 방해 할 수 있습니다.
— akostadinov

3

요소를보기로 스크롤하기위한 Ruby 스크립트는 다음과 같습니다.

$driver.execute_script("arguments[0].scrollIntoView(true);", element)
sleep(3)
element.click

2

때때로 나는 또한 셀레늄으로 스크롤하는 문제에 직면했다. 그래서 이것을 달성하기 위해 javaScriptExecuter를 사용했습니다.

아래로 스크롤하는 경우 :

WebDriver driver = new ChromeDriver();
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("window.scrollBy(0, 250)", "");

또는

js.executeScript("scroll(0, 250);");

위로 스크롤 :

js.executeScript("window.scrollBy(0,-250)", "");

또는,

js.executeScript("scroll(0, -250);");

2

다른 답변이 너무 해킹되었다고 생각하면 이것도 마찬가지이지만 JavaScript 삽입은 없습니다.

버튼이 화면을 벗어나면 버튼이 깨져 스크롤되므로 다시 시도하십시오 ... ¯ \ _ (ツ) _ / ¯

try
{
    element.Click();
}
catch {
    element.Click();
}

2

이것은 JavaScript에서 반복되는 솔루션이지만 요소 대기가 추가되었습니다.

그렇지 않으면 ElementNotVisibleException요소에 대한 조치가 수행되는 경우 나타날 수 있습니다.

this.executeJavaScriptFunction("arguments[0].scrollIntoView(true);", elementToBeViewable);
WebDriverWait wait = new WebDriverWait(getDriver(), 5);
wait.until(ExpectedConditions.visibilityOf(elementToBeViewable));

?? <-무슨 뜻입니까?
— Choi

1

이 방법으로 요소를 스크롤하고 클릭했습니다.

List<WebElement> image = state.getDriver().findElements(By.xpath("//*[contains(@src,'image/plus_btn.jpg')]"));

for (WebElement clickimg : image)
{
  ((JavascriptExecutor) state.getDriver()).executeScript("arguments[0].scrollIntoView(false);", clickimg);
  clickimg.click();
}

제 경우에는 scrollIntoView(false)효과가 있었지만 효과 scrollIntoView(true)가 없었습니다. 작동 할 수 있으며 시나리오에 따라 다릅니다.
— rsenna

내 경우는 반대입니다-진정한 작동, 거짓 실패, 그러나 클릭이 발생하는 한. 그것은 거짓으로 올바르게 스크롤되며, 내가 선호하는 것이지만 어떤 이유로 든 셀레늄은 여전히 ​​클릭으로 볼 수 없습니다. 진정한 스크롤을 사용하면 모든 것이 너무 높아지지만 적어도 작동합니다.
— Bill Hileman

사용자 센드 키는 가능하면 클릭 대신 입력됩니다. 브라우저가 100 % 확대되지 않은 경우 문제가 발생하지 않습니다.
— Zunair

1
def scrollToElement(element: WebElement) = {
  val location = element.getLocation
  driver.asInstanceOf[JavascriptExecutor].executeScript(s"window.scrollTo(${location.getX},${location.getY});")
}

1

Javascript를 사용하여 페이지 스크롤 웹 요소 및 웹 페이지 Selenium WebDriver 를 방문 할 수 있습니다 .

public static void main(String[] args) throws Exception {

    // TODO Auto-generated method stub
    FirefoxDriver ff = new FirefoxDriver();
    ff.get("http://toolsqa.com");
    Thread.sleep(5000);
    ff.executeScript("document.getElementById('text-8').scrollIntoView(true);");
}

@AbhishekBedi Chrome에서도 지원한다는 것을 기억합니다. 직면 한 특정 문제가 있습니까?
— virusrocks

1

대부분의 상황에서이 코드를 스크롤하면 작동합니다.

WebElement element = driver.findElement(By.xpath("xpath_Of_Element"));                 
js.executeScript("arguments[0].click();",element);

1

자바

요소 활용 x y위치로 스크롤을 시도 하고 JavascriptExecutor인수와 함께 사용 하십시오 "window.scrollBy(x, y)".

수입 후 :

import org.openqa.selenium.WebElement;
import org.openqa.selenium.JavascriptExecutor;

먼저 x y요소의 위치를 ​​파악 해야 합니다.

//initialize element
WebElement element = driver.findElement(By.id("..."));

//get position
int x = element.getLocation().getX();
int y = element.getLocation().getY();

//scroll to x y 
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("window.scrollBy(" +x +", " +y +")");


0

셀레늄의 기본 동작은 스크롤하여 요소가 뷰포트 상단에서 거의 보이지 않게하는 것입니다. 또한 모든 브라우저가 똑같은 동작을하는 것은 아닙니다. 이것은 매우 불만족입니다. 내가하는 것처럼 브라우저 테스트 비디오를 녹화하면 원하는 요소 를 스크롤하여 세로로 중앙에 위치시키는 것입니다. 입니다.

Java에 대한 내 솔루션은 다음과 같습니다.

public List<String> getBoundedRectangleOfElement(WebElement we)
{
    JavascriptExecutor je = (JavascriptExecutor) driver;
    List<String> bounds = (ArrayList<String>) je.executeScript(
            "var rect = arguments[0].getBoundingClientRect();" +
                    "return [ '' + parseInt(rect.left), '' + parseInt(rect.top), '' + parseInt(rect.width), '' + parseInt(rect.height) ]", we);
    System.out.println("top: " + bounds.get(1));
    return bounds;
}

그런 다음 스크롤하려면 다음과 같이 호출하십시오.

public void scrollToElementAndCenterVertically(WebElement we)
{
    List<String> bounds = getBoundedRectangleOfElement(we);
    Long totalInnerPageHeight = getViewPortHeight(driver);
    JavascriptExecutor je = (JavascriptExecutor) driver;
    je.executeScript("window.scrollTo(0, " + (Integer.parseInt(bounds.get(1)) - (totalInnerPageHeight/2)) + ");");
    je.executeScript("arguments[0].style.outline = \"thick solid #0000FF\";", we);
}

getViewPortHeight 함수가 누락되었습니다 ... 가정에서 대상 요소의 높이를 사용한다고 가정합니다.
— Shubham Jain

0

다음은 Selenium 용 PHP webDriver로 수행하는 방법입니다. Selenium 독립형 서버 2.39.0 + https://github.com/Element-34/php-webdriver + Firefox 25.0에서 작동합니다.

$element=$session->welement("xpath", "//input[@value='my val']");
$element->click();
$element=$session->welement("xpath", "//input[@value='ma val2']");
$element->location_in_view(); // < -- this is the candy
$element->click();

참고 : Element34 PHP-webdriver의 사용자 정의 버전을 사용합니다. 그러나 핵심에는 변화가 없습니다. 난 그냥 "element"대신 "welement"를 사용합니다. 그러나 해당 사건에 영향을 미치지 않습니다. 드라이버 작성자는 "거의 모든 API 호출이 WebDriver 프로토콜 자체에 정의 된 내용을 직접 변환 할 수 있도록한다"고 말합니다. 따라서 다른 프로그래밍 언어에는 아무런 문제가 없습니다.

설정에서 클릭만으로는 작동하지 않습니다. 클릭 대신 스크롤을 수행하므로 "location_in_view ()"를 호출하지 않고 두 번 클릭해야했습니다.

참고 :이 방법은 단추 유형의 입력처럼 볼 수있는 요소에 적용됩니다.

보세요: http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/element/:id/location을 .

JsonWireProtocol #에 대한 설명은 location _in_view가 내부 메소드이므로 location + moveto의 사용법을 제안합니다.


0

나를 위해 일한 것은 브라우저 창의 아래쪽에있는 요소에서 Browser.MoveMouseToElement 메서드를 사용하는 것이 었습니다. 기적적으로 Internet Explorer, Firefox 및 Chrome에서 작동했습니다.

나는 덜 해킹 된 느낌 때문에 JavaScript 주입 기술보다 이것을 선택했습니다.


어떤 프로그래밍 언어입니까?
— akostadinov

0

ADF 구성 요소를 사용하여 테스트를 수행했으며 지연 로딩이 사용되는 경우 별도의 스크롤 명령이 있어야합니다. 객체가로드되지 않고 Selenium을 사용하여 찾으려고하면 Selenium은 발견 할 수없는 요소 예외를 처리합니다.


0

아무것도 작동하지 않으면 다음을 클릭하기 전에 시도하십시오.

public void mouseHoverJScript(WebElement HoverElement) {

    String mouseOverScript = "if(document.createEvent){var evObj = document.createEvent('MouseEvents');evObj.initEvent('mouseover', true, false); arguments[0].dispatchEvent(evObj);} else if(document.createEventObject) { arguments[0].fireEvent('onmouseover');}";
    ((JavascriptExecutor) driver).executeScript(mouseOverScript, HoverElement);
}

0

Java에서는 다음 코드와 같이 JavaScript를 사용하여 스크롤 할 수 있습니다.

driver.getEval("var elm = window.document.getElementById('scrollDiv'); if (elm.scrollHeight > elm.clientHeight){elm.scrollTop = elm.scrollHeight;}");

"elm.scrollTop"변수에 원하는 값을 지정할 수 있습니다.


0

해결책은 다음과 같습니다.

public void javascriptclick(String element)
{
    WebElement webElement = driver.findElement(By.xpath(element));
    JavascriptExecutor js = (JavascriptExecutor) driver;

    js.executeScript("arguments[0].click();", webElement);
    System.out.println("javascriptclick" + " " + element);
}

0

이 코드는 저에게 효과적입니다.

JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("javascript:window.scrollBy(250, 350)");

나를 위해 작동합니다. Dart WebDriver 구현에는 아직 조치가 없습니다.
— Günter Zöchbauer
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.