Selenium으로 페이지를 다루다 보면, 아래쪽에 있는 링크나 버튼을 클릭하려고 할 때 "element not interactable" 이나 "다른 요소가 클릭을 가로챘다"는 식의 예외가 자주 납니다. 요소가 화면 밖에 있거나 고정 헤더 같은 다른 요소에 가려져 있어서 생기는 일인데, 클릭하기 전에 그 요소 위치로 먼저 스크롤해 주면 대부분 해결됩니다. 아래 코드에서 IE 는 WebDriver 인스턴스 변수 이름입니다.

    ActivateElement(IE.FindElement(By.LinkText("쇼핑 더보기")))
    ActivateElement.SendKeys("")

또는

    Imports OpenQA.Selenium.Interactions    ' 추가

    ActivateElement(IE.FindElement(By.LinkText("쇼핑 더보기")))

    Private Function ActivateElement(ByVal CurrentElement As IWebElement) As Boolean
        Try
            Dim act As Actions = New Actions(IE)
            act.MoveToElement(CurrentElement)
            act.Perform()
            Return True
        Catch ex As Exception
        End Try
        Return False
    End Function

방법 1 - 빈 문자열 SendKeys

요소에 키 입력을 보내려면 드라이버가 먼저 그 요소를 화면에 보이게 하고 포커스를 줍니다. 그 성질을 이용해서 아무 글자도 없는 SendKeys("") 를 보내면, 실제로 입력되는 건 없이 스크롤과 포커스 이동만 일어납니다.

다만 위에 적힌 첫 번째 코드는 함수 이름 ActivateElement 에 .SendKeys 를 붙인 형태라 그대로는 원하는 대로 동작하지 않습니다. 의도는 요소를 변수로 받아 두고 거기에 빈 키를 보내는 것이니, 이렇게 쓰는 게 맞습니다.

    Dim el As IWebElement = IE.FindElement(By.LinkText("쇼핑 더보기"))
    el.SendKeys("")

링크나 입력창처럼 포커스를 받을 수 있는 요소에서는 잘 되지만, 포커스를 받지 않는 div 같은 요소에서는 예외가 나거나 스크롤이 안 될 수 있습니다.

방법 2 - Actions.MoveToElement

두 번째 방법은 Selenium의 Actions 클래스로 마우스를 그 요소 위로 옮기는 동작을 실행합니다. 마우스를 옮기려면 요소가 화면에 있어야 하니 드라이버가 알아서 스크롤해 줍니다. OpenQA.Selenium.Interactions 를 Imports 해야 Actions 를 쓸 수 있고, Perform() 을 불러야 실제로 동작이 실행됩니다. 마우스를 올려야 펼쳐지는 메뉴(호버 메뉴)를 다룰 때도 같은 코드를 씁니다.

함수는 성공하면 True, 예외가 나면 조용히 False 를 돌려줍니다. 요소가 이미 사라졌거나(StaleElementReference) 크기가 0이라 이동할 수 없을 때 프로그램이 멈추지 않게 하려는 처리입니다.

방법 3 - 자바스크립트로 직접 스크롤

위 두 방법으로도 안 되면 브라우저에 스크롤 스크립트를 직접 실행하는 게 가장 확실합니다.

    Dim el As IWebElement = IE.FindElement(By.LinkText("쇼핑 더보기"))
    CType(IE, IJavaScriptExecutor).ExecuteScript("arguments[0].scrollIntoView({block:'center'});", el)

block:'center' 로 요소를 화면 가운데에 오게 하면, 상단 고정 메뉴에 가려지는 문제까지 같이 피할 수 있습니다. 스크롤 직후 바로 클릭하면 부드러운 스크롤 애니메이션이 끝나기 전이라 실패하는 사이트도 있으니, 짧게 기다렸다가 클릭하거나 WebDriverWait 으로 클릭 가능한 상태가 될 때까지 기다리는 걸 같이 쓰면 안정적입니다.