首页 > 技术文章 > python + selenium相关事件和元素定位

bencakes 2016-05-20 14:32 原文

同事由于工作上的失误,将公司RDM中的某一字段的2000条数据给删除了.....就算是重新添加字段,但是与其他数据的关联性已经不在了。由于每天的数据修改量大,有关部门不愿意恢复数据库,因此只能一条条的手动添加啦。我看了下添加流程,估计了修改一条信息至少需要30s,那么2000条数据所需要的时间.....数据还在不停的变动,每天上班还有其他事情。身为程序猿的我,只好拿出自动化终极工具Selenium来拯救她了!

一. 元素定位问题

一些基本的元素定位方法,官方文档上面已经有详细的说明了。这里就不啰嗦了,我一般是使用的XPATH定位,写一下我遇到的一些问题。

使用find_element_by_xxx('div')其实都是调用find_element(By.xxx,'div')
XPATH为例,css,id,class等都是同理


##这是源代码中对find_element_by_xpath的定义
def find_element_by_xpath(self, xpath):
    """
    Finds an element by xpath.

    :Args:
     - xpath - The xpath locator of the element to find.

    :Usage:
        driver.find_element_by_xpath('//div/td[1]')
    """
    return self.find_element(by=By.XPATH, value=xpath)

browser.find_element_by_xpath('//div[@id="home"]/span')
##等价于
browser.find_element(By.XPATH, '//div[@id="home"]/span')

**注: **如果你是想查找某个元素列表的话,例如ul下的所有li,记得是使用find_elements,而不是find_element.
**注: **如果你想查找ul下的li中符合某一标准的那个li。例如,你想查找所有li中内容为海贼王的那个li

li = browser.find_element_by_xpath("//ul/li[contains(text(),'海贼王')]")

另外:有时,你需要定位的元素在页面上需要滚动几下才能显示。在我的实践中,这种情况不需要加滚动事件,直接可以通过xpath定位后click()。比如下拉框菜单内容很多的时候,点击下拉框,让下拉菜单显示出来之后,就可以直接定位到所有菜单选项。

二. 使用WebElement.text获取内容问题

文档中的说明:
People often wish to retrieve the innerText value contained within an element. This returns a single string value. Note that this will only return the visible text displayed on the page.
用text获取值,只能获取到当时在页面上能显示出来的值。比如下拉框,想要获取下拉框里面选项的值,需要点击下拉框,将下拉菜单显示出来之后再获取,不然获取的都是空值。

三. iframe问题

iframe中的元素不能直接的定位,需要使用browser.switch_to.frame("frameId")先切换到iframe下,然后定位。

##iframe是内嵌关系,需要到最里层的createFrame中去
browser.switch_to.frame('main')
browser.switch_to.frame('undefined_frame')
browser.switch_to.frame('createFrame')

如果你将这种代码放入到了循环中,记得要在每一个循环开始或结束后加上browser.switch_to.default_content()还原到顶层html


for i in range(10):
    browser.switch_to.default_content()
    browser.switch_to.frame('main')
    browser.switch_to.frame('undefined_frame')
    browser.switch_to.frame('createFrame')
    ##
    #   定位createFrame中的元素
    #   ...
    ###

四. ElementNotVisibleException等异常

好多次碰到这种异常,还有can not clickable这种异常,明明是存在的元素,在循环运行时突然就来了这么个异常,原因估计是因为浏览器的速度跟不上程序运行的速度,导致程序已经开始搜索某个元素时,浏览器还没有解析完成,就会导致各种异常,使用time.sleep(2)来休眠一下一般都可以解决问题,但是使用browser.implicitly_wait(2)好像不行。

推荐阅读