问题描述:

I'm using Selenium to click a button on a website. The button is choosing a state. When the drop-down. The elements are not initially visible. You need to click on the "select" button and then a drop down appears.

The select element looks like this.

<select name="state" style="display: none;">

<option value="0">select</option>

<option value="1">Alabama</option>

<option value="2">Alaska</option>

<option value="3">Arizona</option>

<option value="4">Arkansas</option>

<option value="5">California</option>

I've tried it using:

driver.find_element_by_xpath("/html/body/div[1]/div[3]/form/div/div[9]/div[2]/div/div/div[1]").click()

driver.find_element_by_xpath(state_xpath).click()

The first statement clicks the select buttons so that options appear. The second statement chooses the option by clicking on it. This works fine for the first few options but when I need to choose an option that isn't visible it returns the ElementNotVisibleException

When I try to find it using the select class. It again returns ElementNotVisible. This may be because the display is set to none for this element so the code below doesn't work either.

select = Select(driver.find_element_by_name('state'))

select.select_by_value('2')

How do I work around this. Is there any way to scroll down the options so that more of them become visible.

网友答案:

In your case, I guess there are two solutions. Here are my Java methods, hopefully it may be similar in Python.

1) Make your webdriver wait until the element is visible (useful when "select" elements appear in fade-in).

This one may work but I do not recommend it because it's not dynamic:

Thread.sleep(2); // or whatever

Better use:

public void waitUntilElementDisplayed(By by){
    int timeOut = 10; // you can also define this time-out as a global variable as it may be useful in other methods
    boolean isExpectedElementDisplayed = driver.findElement(by).isDisplayed();
    int count= 0;
    while(!isExpectedElementDisplayed && (count< timeOut)) {
        isExpectedElementDisplayed = driver.findElement(by).isDisplayed();
        Thread.sleep(1);
        count++;
    }
}

2) Scroll down

A little bit :

public void tinyScroll() {
    JavascriptExecutor jse = (JavascriptExecutor) driver;
    jse.executeScript("window.scrollTo(0, 100);");
}

The hole page:

public void scrollToBottomOfPage() {
    JavascriptExecutor jse = (JavascriptExecutor) driver;
    jse.executeScript("window.scrollTo(0,Math.max(document.documentElement.scrollHeight,document.body.scrollHeight,document.documentElement.clientHeight));");
}

After that, if you still get the error, check that you xpath matches one and only one element (if not, Selenium will try to interact with the first occurrence, even if it's hidden, and you'll get an error). In your case I think it's fine because your xpath is very long and specific. But be careful, xpath like this are more fragile when devs refactor the front-end. When possible, it's safer to use html ids.

网友答案:

For anyone stuck on the same problem. The issue here is that the element is not visible. Since I was unable to solve it using driver.execute_script. I found a solution by making the mouse click on the scroll bar so as to scroll it down (By pressing just below the bar itself so that it moves down). I first added a function click that clicks on an x and y position. And ran it whenever I needed a certain element to be visible.

You can easily find x and y location by using a freeware software to do the job.

import win32api, win32con
def click(x,y):
    win32api.SetCursorPos((x,y))
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,x,y,0,0)
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,x,y,0,0)
相关阅读:
Top