这篇主要介绍 Selenium WebDriver 详细的工作过程,介绍到通信层,Browser Driver 的工作原理不去做深入探究。
从上一篇的一个自动化脚本实例开始:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome()
driver.get("http://www.python.org")
assert "Python" in driver.title
elem = driver.find_element_by_name("q")
elem.send_keys("pycon")
elem.send_keys(Keys.RETURN)
assert "No result found." not in driver.page_source
driver.close()
这个脚本模拟的用户操作,在上一篇中已经介绍过了,这里不再赘述。
自动化脚本中的每一个 Selenium Command 都会创建一个带有 Path 的 HTTP request。
当自动化脚本执行的时候,第一个 HTTP request 会创建一个新的 Session,接下来对浏览器的操作将通过这个 Session 来执行。
创建的 Session ID 将用于标识后续的自动化脚本都在同一个 Session 中执行。
HTTP Method | URI Template |
---|---|
POST | /session |
JSON 参数:
返回值:
下面通过几个具体的例子介绍 HTTP request 的具体内容:
HTTP request 的类型是 GET 或者 POST
通常是一些查询命令,用于获取页面中 Web 元素的信息,例如:
以检查一个元素是否已在当前页面中加载成功 —— is_displayed() 为例
HTTP Method | URI Template |
---|---|
GET | /session/{session id}/element/{id}/displayed |
URI 参数:
返回值:
通常是一些操作命令,用于 Web 元素的交互操作,例如:
以点击一个元素 —— element.click() 为例
HTTP Method | URI Template |
---|---|
POST | /session/{session id}/element/{id}/click |
URI 参数:
返回值:
URI 参数(上述例子中已经提到过)
这里说明下 JSON 参数,以获取一个元素为例 —— find_element
HTTP Method | URI Template |
---|---|
POST | /session/{session id}/element |
这里有URL 参数{session id}
JSON 参数:
一个使用 XPath 策略获取元素的 python 脚本写法:
login_form = driver.find_element_by_xpath("//form[@id='loginForm']")
可用的策略有:
State | Keyword |
---|---|
CSS selector | "css selector" |
Link text selector | "link text" |
Partial link text selector | "partial link text" |
XPath | "xpath" |
以获取当前页面的标题 —— driver.title 为例
HTTP Method | URI Template |
---|---|
POST | /session/{session id}/title |
返回值是:一个{string} —— 当前页面的 Title 属性的值
以上述的获取一个元素 —— find_element 为例
返回值是:目标位置的一个 WebElement JSON 对象
Browser Driver 一般是一个 EXE(可执行)程序,或者浏览器的扩展程序,它使用 HTTP Server 持续监听 Selenium2 Commands
其功能有:
这里说明下 “Selenium Commands 对应的用户操作” 具体的内容,以 driver.title(获取页面标题)为例:
HTTP Method | URI Template |
---|---|
POST | /session/{session id}/title |
返回的是页面 Document 的top-level browsing context的 title,等同于调用window.top.document.title。
这个过程中Remote End(Driver 的 Server)对 HTTP request 做出响应的执行步骤是: