通过Selenium,Python中的xpath检测用户可见元素(仅在视口中)

时间:2018-07-07 12:20:46

标签: python selenium-webdriver

我试图仅单击实际上对用户可见的元素,即不要单击我当前在网站上滚动到的位置之外的元素。

我设法检测出所有隐藏的元素,但是如何获取普通用户只能看到的元素列表。

1 个答案:

答案 0 :(得分:0)

如果我理解正确,那么您正在查找一堆这样的元素:

$_GET['roomid']

它将为您提供元素列表。这些元素中有些是可见的,有些则不是。要证明这一点,您可以使用以下方法:

elements = driver.find_elements_by_xpath("//a")

尝试以下代码段:

for element in elements:
    print(element.is_displayed()) # prints true if displayed, otherwise false

输出:

driver = webdriver.Chrome("C:\\path\\to\\chromedriver.exe")
url = "https://stackoverflow.com/"
driver.get(url)

elements = driver.find_elements_by_xpath("//a") # finds all elements by given xPath
for element in elements: # for every element in elements list
    print(element.is_displayed()) # print 'true' if displayed, or 'false' if not

print("DONE")

注意:只是一个例子,通常必须等到页面完全加载才能正确定位所有元素并获得正确的状态。

编辑:我在此question中找到了一个不错的解决方案,这种情况下的示例代码如下:

False
True
False
True
True
True
True
True
True
False
False
False
False
...
DONE

输出:

driver = webdriver.Chrome("C:\\path\\to\\chromedriver.exe")
url = "https://stackoverflow.com/"
driver.get(url)

time.sleep(3)
elements = driver.find_elements_by_xpath("//span")

def element_in_viewport(driver, elem):
    elem_left_bound = elem.location.get('x')
    elem_top_bound = elem.location.get('y')
    elem_width = elem.size.get('width')
    elem_height = elem.size.get('height')
    elem_right_bound = elem_left_bound + elem_width
    elem_lower_bound = elem_top_bound + elem_height

    win_upper_bound = driver.execute_script('return window.pageYOffset')
    win_left_bound = driver.execute_script('return window.pageXOffset')
    win_width = driver.execute_script('return document.documentElement.clientWidth')
    win_height = driver.execute_script('return document.documentElement.clientHeight')
    win_right_bound = win_left_bound + win_width
    win_lower_bound = win_upper_bound + win_height

    return all((win_left_bound <= elem_left_bound,
                win_right_bound >= elem_right_bound,
                win_upper_bound <= elem_top_bound,
                win_lower_bound >= elem_lower_bound)
               )

for element in elements:
    print(element_in_viewport(driver, element))

print("DONE")

我认为此代码段效果很好。