3.Selenium Python导航


导航

你用WebDriver要做的第一件事就是指定一个链接,一般我们使用get方法:

driver.get("http://www.google.com")

WebDriver会等待页面完全加载完(就是onload函数被触发了),才把程序的控制权交给你的测试或者脚本。 但是如果你的页面用了太多的AJAX,那么这个机制就没什么卵用了,因为它不知道页面到底是什么时候加载完。如果你需要确定页面完全加载完了,你可以使用waits

页面交互

我们比较喜欢做的事情就是和页面交互,准确的说,是和页面里的HTML元素交互。首先,我们要找到一个元素,WebDrive提供了许多方法查找元素,例如,给定一个这样的元素:

<input type="text" name="passwd" id="passwd-id" />

你可以用下列任意方法找到它:

element = driver.find_element_by_id("passwd-id")
element = driver.find_element_by_name("passwd")
element = driver.find_element_by_xpath("//input[@id='passwd-id']")

你也可以通过文本信息来找到一个链接,但是要注意,文本必须要完全匹配。 在使用XPATH的时候也要注意,如果有多个元素匹配,只会返回第一个。如果匹配不到任何元素,会抛出一个NoSuchElementException异常。

WebDriver有一个 基于对象的 API,我们可以通过同一个接口代表所有类型的元素,这意味着当你敲击你IDE的自动补全组合键的时候,虽然你会看到你可以调用很多方法,但不是所有的方法都行得通。不过不要担心!WebDriver会自己尝试做正确的选择。并且如果你调用一个没用的方法(例如在一个meta标签上调用setSelected()),WebDriver会抛出一个异常

那么,当你获取到一个元素之后,你可以做些什么呢?首先,你可能会想输入一些文本到一个文本区域:

element.send_keys("some text")

你可以使用Keys类来模拟输入方向键:

element.send_keys(" and some", Keys.ARROW_DOWN)

理论上任意的元素都可以调用send_keys方法,就是说我们可以测试例如Gmail的键盘快捷键。 send_keys的副作用就是输入文本到文本域不会自动清除,而是会附加到原有的文本后面,我们可以使用clear方法来很方便的清除文本框或者文本域的内容:

element.clear()

填充表单

我们已经知道怎么向一个文本框和文本域输入内容,但是其他元素我们要怎么处理? 你可以触发下拉选框,并且用setSelected方法来让一个选项被选中,处理选择框不会很困难:

element = driver.find_element_by_xpath("//select[@name='name']")
all_options = element.find_elements_by_tag_name("option")
for option in all_options:
    print("Value is: %s") % option.get_attribute("value")
    option.click()

这段代码会找到页面的第一个选择框元素,然后遍历每个选项,输出他们的值,并且依次选中。

你可以看到,这种方式处理选择框不太高效,WebDriver支持许多类,其中包括一个Select的类,给我们提供了许多有用的方法:

from selenium.webdriver.support.ui import Select
select = Select(driver.find_element_by_name('name'))
select.selct_by_index(index)
select.select_by_visible_text("text")
select.select_by_value(value)

WebDriver 也提供了取消选中选项的方法:

select = Select(driver.find_element_by_id('id'))
select.deselect_all()

上面的代码会取消页面第一个选择框的所有选中项。

假设测试中,我们需要所有默认选中项的列表,Select类提供了一个属性:

select = Select(driver.find_element_by_xpath("xpath"))
all_selected_options = select.all_selected.options

获取所有可用的选项:

options = select.options

一旦你填写完表单,一般就要提交表单,一个方法是找到提交按钮然后点击它:

# Assume the button has the ID "submit" :)
driver.find_element_by_id("submit").click()

WebDriver 对每个元素都提供一个submit方法,如果在一个表单内的元素上调用,WebDriver会沿着DOM树往上一直寻找,直到找到一个闭合的表单为止,然后调用submit方法;如果元素不在表单内,那么会抛出一个NoSuchElementException异常。

拖放

你可以使用拖放功能,移动确定数量的元素,或者拖到另一个元素上面:

element = driver.find_element_by_name("source")
target = driver.find_element_by_name("target")

from selenium.webdriver import ActionChains
action_chains = ActionChains(driver)
action_chains.drag_and_drop(element,target).perform()

可以看这个页面的演示

在窗口(window)和框架(frame)间移动

现在的网页应用里没有页面框架或者只用一个窗口就包含了所有内容的已经很少了。WebDriver 支持在指定的窗口间移动,方法为switch_to_window

driver.switch_to_window("windowName")

现在所有的driver的调用都会指向这个给定的窗口,但是我们怎么知道窗口的名字是什么呢?可以看一看打开这个窗口的javascript脚本或者link链接:

<a href="somewhere.html" target="windowName">Click here to open a new window</a>

或者,你可以传一个window handleswitch_to_window()方法,它就可以像这样迭代每一个打开的窗口:

for handle in driver.window_handles:
    driver.switch_to_window(handle)

你也可以在框架和框架之间切换 (or into iframes):

driver.switch_to_frame("frameName")

我们可以用.分离路径来访问子框架,并且可以指定它的索引:

driver.switch_to_frame("frameName.0.child")

这会跳到'frameName'框架内第一个名为'child'的子框架。All frames are evaluated as if from top.

一旦我们操作完了框架,我们可以通过下面的操作回到父框架:

driver.switch_to_default_content()

弹出对话框

Selenium内置支持处理弹出对话框,当你触发了弹框操作,你可以用下面的方法获得对话框元素:

alert = driver.switch_to_alert()

上述代码返回当前打开的对话框对象,有了这个对象 我们可以做确定、忽略、阅读提示文本或者甚至输入prompt,这个接口可以很好的操作alerts、confirms、prompts等对话框。更多内容参阅API文档

导航:历史记录和定位

前面我们可以使用get命令(driver.get("http://www.example.com"))导航到一个页面。如你所见,WebDriver有一些较小的,侧重任务的接口,导航是一个很有用的任务,要打开一个页面,你可以使用get方法:

driver.get("http://www.example.com")

要在浏览器的历史记录的后退或者前进:

driver.forward()
driver.back()

要记得这些函数完全依赖于底层驱动,如果你过去习惯某一个浏览器的运行状态,当切换到新的浏览器时,调用这些方法有可能会出现预料之外的情况。

Cookies

Before we leave these next steps。你可能会好奇如何使用cookie,首先你需要处在一个域名下,然后这样设置cookie:

# Go to the correct domain
driver.get("http://example.com")

# Now set the cookie. This one's valid for the entire domain
cookie = {'name':'foo','value':'bar'}
driver.add_cookie(cookie)

# And now output all the available cookies for the current URL
driver.get_cookies()