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


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.