16 KiB
selenium
Components
Driver
Driver负责控制实际的浏览器,大多数driver是由浏览器供应商提供的。
WebDriver
WebDriver通过Driver和浏览器通信,通过driver, webDriver将命令发送给浏览器,并且通过driver收到浏览器的返回信息。
Drvier和浏览器运行在同一个操作系统上,WebDriver和
drvier&浏览器可能并不运行在同一系统上。WebDriver会远程调用driver,driver再调用处于同一系统的浏览器。
Getting Started
安装
pip install selenium
常用操作
开启浏览器会话
driver = webdriver.Chrome()
通过webdriver执行操作
driver.get("https://www.selenium.dev/selenium/web/web-form.html")
请求浏览器信息
# driver.title代表浏览器当前页签的标题
title = driver.title
指定等待策略
再获取元素之前,需要确保元素存在于当前页面上,并且与元素进行交互时,必须确保当前元素是可交互的(页签加载需要时间)。
此时,可以通过自定义等待时间来解决。
driver.implicitly_wait(0.5)
获取页面上的元素
text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")
针对页面上的元素执行操作
text_box.send_keys("Selenium")
submit_button.click()
访问元素上的信息
text = message.text
关闭会话
driver.quit()
提交表单样例
from selenium import webdriver
from selenium.webdriver.common.by import By
def test_eight_components():
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/web-form.html")
title = driver.title
assert title == "Web form"
driver.implicitly_wait(0.5)
text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")
text_box.send_keys("Selenium")
submit_button.click()
message = driver.find_element(by=By.ID, value="message")
value = message.text
assert value == "Received!"
driver.quit()
Driver
开启和关闭session代表着开启和关闭浏览器。
Browser Options
对于remote driver sessions,需要为其指定options对象,指定的options对象将会决定使用远程的哪个浏览器。
每个浏览器都会有其独属的额外选项,可以为每个浏览器额外指定。
browserName
当使用options对象时,browserName选项会被默认指定:
Driver Service
Service用于管理local driver的启动和停止,service无法被用于remote webdriver session。
service允许指定driver的信息,例如driver位置和使用的端口号,也可以通过service指定日志信息。
使用默认service实例
service = webdriver.ChromeService()
driver = webdriver.Chrome(service=service)
指定driver port
如果想要driver运行在指定的端口,可以通过service进行指定。
service = webdriver.ChromeService(port=1234)
Remote Web Driver
Selenium允许调用位于远程机器上的浏览器,需要远程机器上安装Selenium Grid。
options = webdriver.ChromeOptions()
driver = webdriver.Remote(command_executor=server, options=options)
元素交互
文件上传
通过元素的send_keys方法,支持支持文件上传。
file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
file_input.send_keys(upload_file)
driver.find_element(By.ID, "file-submit").click()
文件定位
在整个dom中进行查找
可以通过调用driver.find_element来在整个dom中对元素进行查找,其会返回匹配的第一个元素
vegetable = driver.find_element(By.CLASS_NAME, "tomatoes")
基于已定位的元素进行查找
如果想要在已经定位元素的子节点中进行查找,可以调用如下方法:
fruits = driver.find_element(By.ID, "fruits")
fruit = fruits.find_element(By.CLASS_NAME,"tomatoes")
css选择器
selenium支持通过css选择器的语法来进行查找:
fruit = driver.find_element(By.CSS_SELECTOR,"#fruits .tomatoes")
查找所有匹配的元素
可以通过find_elements方法来获取所有匹配的元素,而不是第一个匹配的元素
plants = driver.find_elements(By.TAG_NAME, "li")
同web元素进行交互
可以针对元素指定如下类型的交互
- click(可使用任何元素)
- send_keys(只针对文本输入框或内容可编辑的元素)
- clear(只针对文本输入框或内容可编辑的元素)
- submit(只针对表单元素)
- select(只针对下拉框类型元素)
click
# Navigate to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")
# Click on the element
driver.find_element(By.NAME, "color_input").click()
send_keys
# Navigate to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")
# Clear field to empty it from any previous data
driver.find_element(By.NAME, "email_input").clear()
# Enter Text
driver.find_element(By.NAME, "email_input").send_keys("admin@localhost.dev" )
clear
# Navigate to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")
# Clear field to empty it from any previous data
driver.find_element(By.NAME, "email_input").clear()
获取元素信息
is_displayed
# Navigate to the url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")
# Get boolean value for is element display
is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
is_enabled
# Navigate to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")
# Returns true if element is enabled else returns false
value = driver.find_element(By.NAME, 'button_input').is_enabled()
is_selected
# Navigate to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")
# Returns true if element is checked else returns false
value = driver.find_element(By.NAME, "checkbox_input").is_selected()
tag_name
# Navigate to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")
# Returns TagName of the element
attr = driver.find_element(By.NAME, "email_input").tag_name
元素位置和大小
# Navigate to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")
# Returns height, width, x and y coordinates referenced element
res = driver.find_element(By.NAME, "range_input").rect
获取css的值
# Navigate to Url
driver.get('https://www.selenium.dev/selenium/web/colorPage.html')
# Retrieves the computed style property 'color' of linktext
cssValue = driver.find_element(By.ID, "namedColor").value_of_css_property('background-color')
获取文本内容
# Navigate to url
driver.get("https://www.selenium.dev/selenium/web/linked_image.html")
# Retrieves the text of the element
text = driver.find_element(By.ID, "justanotherlink").text
获取元素属性
# Navigate to the url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")
# Identify the email text box
email_txt = driver.find_element(By.NAME, "email_input")
# Fetch the value property associated with the textbox
value_info = email_txt.get_attribute("value")
浏览器交互
获取当前页签的title
String title = driver.getTitle();
获取当前url
String url = driver.getCurrentUrl();
浏览器导航
跳转到页面
driver.get("https://www.selenium.dev/selenium/web/index.html")
返回到上一个页签
driver.back()
forward
driver.forward()
刷新当前页签
driver.refresh()
alert
element = driver.find_element(By.LINK_TEXT, "See an example alert")
element.click()
wait = WebDriverWait(driver, timeout=2)
alert = wait.until(lambda d : d.switch_to.alert)
text = alert.text
# 接受alert
alert.accept()
confirm
element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
driver.execute_script("arguments[0].click();", element)
wait = WebDriverWait(driver, timeout=2)
alert = wait.until(lambda d : d.switch_to.alert)
text = alert.text
alert.dismiss()
prompt
element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
driver.execute_script("arguments[0].click();", element)
wait = WebDriverWait(driver, timeout=2)
alert = wait.until(lambda d : d.switch_to.alert)
alert.send_keys("Selenium")
text = alert.text
alert.accept()
新增cookie
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("http://www.example.com")
# Adds the cookie into current browser context
driver.add_cookie({"name": "key", "value": "value"})
iframe
想要与iframe中的内容进行交互,需要先移动到iframe区域
# Store iframe web element
iframe = driver.find_element(By.CSS_SELECTOR, "#modal > iframe")
# switch to selected iframe
driver.switch_to.frame(iframe)
# Now click on button
driver.find_element(By.TAG_NAME, 'button').click()
winodws/tab 交互
获取当前窗口句柄
driver.current_window_handle
切换窗口句柄
可以通过driver.switch_to.window(windows_handle)来进行切换页签
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
with webdriver.Firefox() as driver:
# Open URL
driver.get("https://seleniumhq.github.io")
# Setup wait for later
wait = WebDriverWait(driver, 10)
# Store the ID of the original window
original_window = driver.current_window_handle
# Check we don't have other windows open already
assert len(driver.window_handles) == 1
# Click the link which opens in a new window
driver.find_element(By.LINK_TEXT, "new window").click()
# Wait for the new window or tab
wait.until(EC.number_of_windows_to_be(2))
# Loop through until we find a new window handle
for window_handle in driver.window_handles:
if window_handle != original_window:
driver.switch_to.window(window_handle)
break
# Wait for the new tab to finish loading content
wait.until(EC.title_is("SeleniumHQ Browser Automation"))
创建新窗口/tab
# Opens a new tab and switches to new tab
driver.switch_to.new_window('tab')
# Opens a new window and switches to new window
driver.switch_to.new_window('window')
关闭tab
调用driver.close会关闭当前的页签
#Close the tab or window
driver.close()
#Switch back to the old tab or window
driver.switch_to.window(original_window)
关闭会话
当不再使用浏览器会话后,应该调用driver.quit()方法。
如果未调用该方法或是调用该方法失败,将会导致driver进程和端口号一直不被释放。
获取窗口大小
# Access each dimension individually
width = driver.get_window_size().get("width")
height = driver.get_window_size().get("height")
# Or store the dimensions and query them later
size = driver.get_window_size()
width1 = size.get("width")
height1 = size.get("height")
设置窗口大小
driver.set_window_size(1024, 768)
获取窗口位置
# Access each dimension individually
x = driver.get_window_position().get('x')
y = driver.get_window_position().get('y')
# Or store the dimensions and query them later
position = driver.get_window_position()
x1 = position.get('x')
y1 = position.get('y')
设置窗口位置
# Move the window to the top left of the primary monitor
driver.set_window_position(0, 0)
最大化窗口
driver.maximize_window()
最小化窗口
driver.minimize_window()
全屏窗口
driver.fullscreen_window()
截屏
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("http://www.example.com")
# Returns and base64 encoded string into image
driver.save_screenshot('./image.png')
driver.quit()
为元素截屏
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("http://www.example.com")
ele = driver.find_element(By.CSS_SELECTOR, 'h1')
# Returns and base64 encoded string into image
ele.screenshot('./image.png')
driver.quit()
执行js脚本
# Stores the header element
header = driver.find_element(By.CSS_SELECTOR, "h1")
# Executing JavaScript to capture innerText of header element
driver.execute_script('return arguments[0].innerText', header)
打印页面
from selenium.webdriver.common.print_page_options import PrintOptions
print_options = PrintOptions()
print_options.page_ranges = ['1-2']
driver.get("printPage.html")
base64code = driver.print_page(print_options)