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

16 KiB
Raw Blame History

selenium

Components

Driver

Driver负责控制实际的浏览器大多数driver是由浏览器供应商提供的。

WebDriver

WebDriver通过Driver和浏览器通信通过driver webDriver将命令发送给浏览器并且通过driver收到浏览器的返回信息。

Drvier和浏览器运行在同一个操作系统上WebDriver和drvier&浏览器可能并不运行在同一系统上。WebDriver会远程调用driverdriver再调用处于同一系统的浏览器。

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)