Files
rikako-note/python/selenium.md
2024-05-06 00:57:09 +08:00

576 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

- [selenium](#selenium)
- [Components](#components)
- [Driver](#driver)
- [WebDriver](#webdriver)
- [Getting Started](#getting-started)
- [安装](#安装)
- [常用操作](#常用操作)
- [开启浏览器会话](#开启浏览器会话)
- [通过webdriver执行操作](#通过webdriver执行操作)
- [请求浏览器信息](#请求浏览器信息)
- [指定等待策略](#指定等待策略)
- [获取页面上的元素](#获取页面上的元素)
- [针对页面上的元素执行操作](#针对页面上的元素执行操作)
- [访问元素上的信息](#访问元素上的信息)
- [关闭会话](#关闭会话)
- [提交表单样例](#提交表单样例)
- [Driver](#driver-1)
- [Browser Options](#browser-options)
- [browserName](#browsername)
- [Driver Service](#driver-service)
- [使用默认service实例](#使用默认service实例)
- [指定driver port](#指定driver-port)
- [Remote Web Driver](#remote-web-driver)
- [元素交互](#元素交互)
- [文件上传](#文件上传)
- [文件定位](#文件定位)
- [在整个dom中进行查找](#在整个dom中进行查找)
- [基于已定位的元素进行查找](#基于已定位的元素进行查找)
- [css选择器](#css选择器)
- [查找所有匹配的元素](#查找所有匹配的元素)
- [同web元素进行交互](#同web元素进行交互)
- [click](#click)
- [send\_keys](#send_keys)
- [clear](#clear)
- [获取元素信息](#获取元素信息)
- [is\_displayed](#is_displayed)
- [is\_enabled](#is_enabled)
- [is\_selected](#is_selected)
- [tag\_name](#tag_name)
- [元素位置和大小](#元素位置和大小)
- [获取css的值](#获取css的值)
- [获取文本内容](#获取文本内容)
- [获取元素属性](#获取元素属性)
- [浏览器交互](#浏览器交互)
- [获取当前页签的title](#获取当前页签的title)
- [获取当前url](#获取当前url)
- [浏览器导航](#浏览器导航)
- [跳转到页面](#跳转到页面)
- [返回到上一个页签](#返回到上一个页签)
- [forward](#forward)
- [刷新当前页签](#刷新当前页签)
- [alert](#alert)
- [confirm](#confirm)
- [prompt](#prompt)
- [新增cookie](#新增cookie)
- [iframe](#iframe)
- [winodws/tab 交互](#winodwstab-交互)
- [获取当前窗口句柄](#获取当前窗口句柄)
- [切换窗口句柄](#切换窗口句柄)
- [创建新窗口/tab](#创建新窗口tab)
- [关闭tab](#关闭tab)
- [关闭会话](#关闭会话-1)
- [获取窗口大小](#获取窗口大小)
- [设置窗口大小](#设置窗口大小)
- [获取窗口位置](#获取窗口位置)
- [设置窗口位置](#设置窗口位置)
- [最大化窗口](#最大化窗口)
- [最小化窗口](#最小化窗口)
- [全屏窗口](#全屏窗口)
- [截屏](#截屏)
- [为元素截屏](#为元素截屏)
- [执行js脚本](#执行js脚本)
- [打印页面](#打印页面)
# selenium
## Components
### Driver
Driver负责控制实际的浏览器大多数driver是由浏览器供应商提供的。
### WebDriver
WebDriver通过Driver和浏览器通信通过driver webDriver将命令发送给浏览器并且通过driver收到浏览器的返回信息。
> Drvier和浏览器运行在同一个操作系统上WebDriver和`drvier&浏览器`可能并不运行在同一系统上。WebDriver会远程调用driverdriver再调用处于同一系统的浏览器。
## Getting Started
### 安装
```bash
pip install selenium
```
### 常用操作
#### 开启浏览器会话
```py
driver = webdriver.Chrome()
```
#### 通过webdriver执行操作
```py
driver.get("https://www.selenium.dev/selenium/web/web-form.html")
```
#### 请求浏览器信息
```py
# driver.title代表浏览器当前页签的标题
title = driver.title
```
#### 指定等待策略
再获取元素之前,需要确保元素存在于当前页面上,并且与元素进行交互时,必须确保当前元素是可交互的(页签加载需要时间)。
此时,可以通过自定义等待时间来解决。
```py
driver.implicitly_wait(0.5)
```
#### 获取页面上的元素
```py
text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")
```
#### 针对页面上的元素执行操作
```py
text_box.send_keys("Selenium")
submit_button.click()
```
#### 访问元素上的信息
```py
text = message.text
```
#### 关闭会话
```py
driver.quit()
```
#### 提交表单样例
```py
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实例
```py
service = webdriver.ChromeService()
driver = webdriver.Chrome(service=service)
```
#### 指定driver port
如果想要driver运行在指定的端口可以通过service进行指定。
```py
service = webdriver.ChromeService(port=1234)
```
### Remote Web Driver
Selenium允许调用位于远程机器上的浏览器需要远程机器上安装Selenium Grid。
```py
options = webdriver.ChromeOptions()
driver = webdriver.Remote(command_executor=server, options=options)
```
## 元素交互
### 文件上传
通过元素的`send_keys`方法,支持支持文件上传。
```py
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中对元素进行查找其会返回匹配的第一个元素
```py
vegetable = driver.find_element(By.CLASS_NAME, "tomatoes")
```
#### 基于已定位的元素进行查找
如果想要在已经定位元素的子节点中进行查找,可以调用如下方法:
```py
fruits = driver.find_element(By.ID, "fruits")
fruit = fruits.find_element(By.CLASS_NAME,"tomatoes")
```
#### css选择器
selenium支持通过css选择器的语法来进行查找
```py
fruit = driver.find_element(By.CSS_SELECTOR,"#fruits .tomatoes")
```
#### 查找所有匹配的元素
可以通过`find_elements`方法来获取所有匹配的元素,而不是第一个匹配的元素
```py
plants = driver.find_elements(By.TAG_NAME, "li")
```
### 同web元素进行交互
可以针对元素指定如下类型的交互
- click可使用任何元素
- send_keys只针对文本输入框或内容可编辑的元素
- clear只针对文本输入框或内容可编辑的元素
- submit(只针对表单元素)
- select只针对下拉框类型元素
#### click
```py
# 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
```py
# 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
```py
# 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
```py
# 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
```py
# 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
```py
# 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
```py
# 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
```
#### 元素位置和大小
```py
# 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的值
```py
# 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')
```
#### 获取文本内容
```py
# 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
```
#### 获取元素属性
```py
# 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
```py
String title = driver.getTitle();
```
### 获取当前url
```py
String url = driver.getCurrentUrl();
```
### 浏览器导航
#### 跳转到页面
```py
driver.get("https://www.selenium.dev/selenium/web/index.html")
```
#### 返回到上一个页签
```py
driver.back()
```
#### forward
```py
driver.forward()
```
#### 刷新当前页签
```py
driver.refresh()
```
#### alert
```py
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
```py
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
```py
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
```py
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区域
```py
# 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 交互
#### 获取当前窗口句柄
```py
driver.current_window_handle
```
#### 切换窗口句柄
可以通过`driver.switch_to.window(windows_handle)`来进行切换页签
```py
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
```py
# 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`会关闭当前的页签
```py
#Close the tab or window
driver.close()
#Switch back to the old tab or window
driver.switch_to.window(original_window)
```
#### 关闭会话
当不再使用浏览器会话后,应该调用`driver.quit()`方法。
如果未调用该方法或是调用该方法失败将会导致driver进程和端口号一直不被释放。
#### 获取窗口大小
```py
# 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")
```
#### 设置窗口大小
```py
driver.set_window_size(1024, 768)
```
#### 获取窗口位置
```py
# 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')
```
#### 设置窗口位置
```py
# Move the window to the top left of the primary monitor
driver.set_window_position(0, 0)
```
#### 最大化窗口
```py
driver.maximize_window()
```
#### 最小化窗口
```py
driver.minimize_window()
```
#### 全屏窗口
```py
driver.fullscreen_window()
```
#### 截屏
```py
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()
```
#### 为元素截屏
```py
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脚本
```py
# 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)
```
#### 打印页面
```py
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)
```