[译]Selenium Python文档:三、导航控制

你使用WebDriver要做的第一件事就是访问一个链接。一般通过调用get方法来实现:

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

在将控制权返给你的脚本之前WebDriver将会等待Web页面完全加载(也就是说,等待onload被触发)。值得注意的是如果你的页面在加载的时候使用了大量的AJAX的话,WebDriver可能不知道什么时候页面已经加载完成。如若你需要确保这类页面被完整加载,可以使用wait等待。

3.1.与页面进行交互

仅仅访问一个页面并没什么大用处。我们真正想做的是和页面进行交互,或者更专业一点的说,和页面中的HTML元素进行交互。首先,我们需要先定位一个页面元素。WebDriver为定位页面元素提供了大量方法。例如,像下面这样定义一个HTML 元素:

<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']")

你也可以通过他的显示文本来定位它。但是请小心——文本必须完全匹配!使用WebDriver XPath的时候也应当格外小心。如果通过查询语句匹配了多个元素,只有第一个会被返回。如果没有找到匹配的,将会抛出一个NoSuchElementException异常。

WebDriver是面向对象的;针对不同元素我们使用相同的接口。这意味着,你的IDE自动补全功能会给你提示很多方法,但他们并不都是有效的,有些使用的话甚至会出错。别太担心!WebDriver将会尝试去做正确的处理。如果你调用了一个无意义的方法(如,对一个“meta”元素进行“setSelected()”操作),WebDriver将会抛出一个异常。

嗯哼,你现在得到了一个元素。你能对他做什么呢?首先,你也许想要在文本输入框中输入一些文本:

element.send_keys("some text")

你可以使用Keys类来模拟敲下-箭头按键:

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

可以对任意的HTML 元素调用send_keys方法,这可以用来测试键盘快捷键,就像GMAIL中使用的那样。这样做的一个副作用是在文本输入框中键入什么的时候不会自动清除它先前的内容,而是直接将你的内容追加到后面。但是你可以使用clear轻松清除掉文本输入框或者文本域的内容:

element.clear()

3.3.填写Form表单

我们已经知道了如何在文本输入框和文本域中输入文字,其他元素又怎么样呢?你可以切换下拉的状态,你可以使用setSelectedOPTION标签的元素设置为选中状态,处理SELECT标签也不错:

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()

这将会找到页面上的第一个SELECT元素,循环遍历OPTIONS,打印出它们的值,并选中它们。

正如你所看到的那样,这不是处理SELECT元素最高效的方法。WebDriver中有一个Select类,提供了处理SELECT相关的高效方法:

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

WebDriver还提供了取消选中的功能:

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

获得所有的可用选项:

options = select.options

一旦你完成了表单的填写,你应该会想提交它。一种方法是找到submit按钮并点击它。

# 假设按钮的ID是"submit" :)
driver.find_element_by_id("submit").click()

除此之外,WebDriver还为每一个元素的提交行为提供了一个简便的方法。如果你对一个表单内的元素调用此方法,WebDriver将会遍历整个DOM直到找到闭合的form标签,并对其调用提交(submit)。如果这个元素不是一个表单,将会抛出一个NoSuchElementException异常:

element.submit()

3.3.拖拽

你可以使用拖拽功能移动元素:

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()

3.4.在窗口和帧之间移动

现代Web应用多是多帧的,很少有单一窗口的了。WebDriver提供了switch_to_window方法来支持命名窗口间的移动切换:

driver.switch_to_window("windowName")

现在driver的所有操作将会针对特定的窗口。但是怎么才能知道窗口的名字呢?看一下js或者html中的超链接:

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

或者你可以给switch_to_window方法传递一个“窗口句柄”。这样我们就可像下面这样遍历每一个窗口的标签:

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

你也可以在帧与帧之间切换(或者iframe之间)

driver.switch_to_frame("frameName")

通过点号分割的路径可以访问子帧,你也可以通过索引指定具体的帧:

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

上边的代码将会进入第一个名为"frameName"的->第一个子帧->的一个名为"child"的子帧。All frames are evaluated as if from top.

我们一旦结束了在frame上的工作,可以返回父帧:

driver.switch_to_default_content()

3.5.弹出式对话框

Selenium WebDriver对处理弹出式对话框提供了内建支持。你触发了相应操作之后将会打开一个弹框,你可以像下面这样访问alert:

alert = driver.switch_to_alert()

这将会返回当前打开的alert对象。通过这个对象你可以进行确认同意,反对,读取它的内容甚至输入一些东西。这个接口对于处理alerts、confirm、prompts同样棒👍。参考官方的API文档了解更多详细信息。

3.6.导航:历史和定位

之前我们知道了通过get命令导航到一个页面(driver.get("http://www.example.com")).如你所见,WebDriver有大量的比较小、专注特定任务的接口。导航是一个非常有用的任务。要导航到一个网页,你可以使用get方法:

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

根据你的浏览器历史进行前进回退

driver.forward()
driver.back()

请认识到这个功能完全依赖所使用的驱动器。在你使用不同的浏览器的时,调用这些方法完全有可能出现未预料的情形。

3.7.Cookies

再继续下一章之前,也许你会对怎么使用cookie感兴趣。首先,你需要在cookie所对应的有效域名下:

# 打开正确的域名
driver.get("http://www.example.com")

# 设置cookie. 这将在整个域名内有效
cookie = {‘name’ : ‘foo’, ‘value’ : ‘bar’}
driver.add_cookie(cookie)

# 打印出当前URL所有有效的cookie
driver.get_cookies()
posted @ 2017-03-22 23:16  Tacey Wong  阅读(2098)  评论(0编辑  收藏  举报