Selenium

Selenium基础

selenium运行原理

  1. 自动化程序调用Selenium客户端库函数(比如点击按钮元素)
  2. 客户端库会发送Selenium命令给浏览器的驱动程序
  3. 浏览器驱动程序接收到命令后,驱动浏览器去执行命令
  4. 浏览器执行命令
  5. 浏览器驱动程序获取命令执行的结果,返回给我们自动化程序
  6. 自动化程序对返回结果进行处理

最大化、最小化、前进、后退、刷新、关闭

import time
from selenium import webdriver

driver = webdriver.Chrome()
url = "https://petstore.octoperf.com/actions/Catalog.action"
driver.get(url)
time.sleep(2)
driver.minimize_window()  # 最小化
time.sleep(2)
driver.maximize_window()  # 最大化
time.sleep(2)
driver.get("https://www.douyin.com/")  # 访问另一个网址
time.sleep(2)
driver.back()  # 后退
time.sleep(2)
driver.forward()  # 前进
time.sleep(2)
driver.refresh()  # 刷新
time.sleep(2)
driver.close()  # 关闭

隐性等待

import time
from selenium import webdriver

driver = webdriver.Chrome()
driver.implicitly_wait(10)  # 设置隐性等待
url = "https://www.baidu.com/"
driver.get(url)
# 输入框搜索
driver.find_element("id",'kw').send_keys("哈")
driver.find_element("id",'su').click()
driver.find_element("xpath",'//span[contains(text(),"百度汉语")]')
time.sleep(3)
driver.close()

隐性等待

隐性等待一般配合.until()使用

from selenium.webdriver.support.wait import WebDriverWait
WebDriverWait(driver, 超时时长, 调用频率(可选,有默认值), 忽略异常(可选,有默认值)).until(可执行方法, 超时时返回的信息)

EC模块常用函数

from selenium.webdriver.support import expected_conditions as EC

EC.presence_of_element_located(locator)  # 判断一个元素是否存在,locator为一个元组,最经常使用的函数
EC.element_to_be_clickable(locator)  # 判断元素是否可点击
import time
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions

driver = webdriver.Chrome()
# driver.implicitly_wait(10)  # 设置隐性等待
url = "https://www.baidu.com/"
driver.get(url)
driver.find_element("id",'kw').send_keys("哈")
driver.find_element("id",'su').click()
wait = WebDriverWait(driver, 10)  # 初始化一个等待器
locator = ("xpath",'//span[contains(text(),"百度汉语")]')
# 直到
el = wait.until(expected_conditions.element_to_be_clickable(locator))
# WebDriverWait(driver, 10).until(expected_conditions.element_to_be_clickable(("xpath",'//span[contains(text(),"百度汉语")]')))
time.sleep(3)
driver.quit()

click点击

import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

option = Options()
option.page_load_strategy = "eager"
driver = webdriver.Chrome(options=option)
driver.implicitly_wait(60)
driver.get("https://letcode.in/buttons")
time.sleep(2)
print(driver.find_element("id","home").get_attribute("outerHTML"))  # 打印该按钮的全部属性
driver.find_element("id","home").click()
assert driver.title == 'LetCode with Koushik'
driver.save_screenshot("./picture/bbb.png")
time.sleep(3)
driver.quit()

input文本输入

import time
from selenium import webdriver
from selenium.webdriver import Keys
from selenium.webdriver.chrome.options import Options

option = Options()
option.page_load_strategy = "eager"
driver = webdriver.Chrome(options=option)
driver.implicitly_wait(60)
driver.get("https://letcode.in/edit")
driver.find_element("id","fullName").send_keys("ppp")
driver.find_element("xpath","//input[@value='I am good']").clear()  # 清除文本框中的内容
driver.save_screenshot("./picture/aaa.png")
time.sleep(3)
driver.quit()

# 其他
driver.find_element("id", "s").send_keys("mysql")
driver.find_element("id", "s").send_keys(Keys.CONTROL,"a")  # 全选
driver.find_element("id", "s").send_keys(Keys.CONTROL,"c")  # 复制
driver.find_element("id", "s").send_keys(Keys.CONTROL,"v")  # 粘贴
print(driver.find_element("id", "s").get_attribute("value"))  # 获取输入框内的文本值
print(driver.find_element("id", "s").tag_name)  # 获取元素的标签名称
driver.find_element("id", "s").send_keys(Keys.ENTER)  # 回车键
driver.find_element("id", "s").submit()  # 回车键

radio&checkbox单选按钮及复选框

import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

option = Options()
option.page_load_strategy = "eager"
driver = webdriver.Chrome(options=option)
driver.implicitly_wait(60)
driver.get("https://letcode.in/radio")
time.sleep(2)


def is_select(locator):  # 简单封装
    el = driver.find_element(*locator)
    if el.is_selected():  # 判断单选框是否被选中
        print("已经选择")
        pass
    else:
        el.click()


# driver.find_element("id","yes").click()
is_select(("id", "yes"))
time.sleep(2)
is_select(("id", "two"))
time.sleep(2)
is_select(("id", "notfoo"))
time.sleep(3)
driver.save_screenshot("./picture/rrr.png")
driver.quit()

alert弹窗

import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

option = Options()
option.page_load_strategy = "eager"
driver = webdriver.Chrome(options=option)
driver.implicitly_wait(60)
driver.get("https://letcode.in/alert")
driver.find_element("class name", "is-link").click()
time.sleep(2)
print(driver.switch_to.alert.text)  # 打印弹窗上现实的文本
driver.switch_to.alert.accept()  # 点击确定

driver.find_element("id", "confirm").click()
time.sleep(2)
driver.switch_to.alert.dismiss()  # 点击取消

driver.find_element("id", "prompt").click()
time.sleep(2)
driver.switch_to.alert.send_keys("prompt")  # 在 弹窗 上输入文本
time.sleep(2)
driver.switch_to.alert.accept()

driver.find_element("id", "modern").click()
time.sleep(3)
driver.find_element("class name", "modal-close").click()

time.sleep(3)
driver.quit()

select下拉框

import time

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.select import Select

option = Options()
option.page_load_strategy = "eager"
driver = webdriver.Chrome(options=option)
driver.implicitly_wait(60)
driver.get("https://letcode.in/dropdowns")
select_x = driver.find_element("id", "fruits")
for i in ["header", "0", "1", "2", "3", '4']:
    Select(select_x).select_by_value(i)  # 通过 value 定位
    driver.save_screenshot(f"./picture/ccc_value{i}.png")
    time.sleep(2)

# for i in range(5):
#     Select(select_x).select_by_index(i)  # 通过索引定位
#     time.sleep(2)

# for i in ["Select Fruit","Apple","Mango","Orange","Banana",'Pine Apple']:
#     Select(select_x).select_by_visible_text(i)  # 通过下拉框text定位
#     time.sleep(2)

select_y = driver.find_element("id", "superheros")
for i in ["am", "bt", "ca", "ds", "ff", 'im']:
    Select(select_y).select_by_value(i)
    time.sleep(2)

driver.quit()

frame标签

import time

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

option = Options()
option.page_load_strategy = "eager"
driver = webdriver.Chrome(options=option)
driver.implicitly_wait(60)
driver.get("https://letcode.in/frame")
time.sleep(2)

# driver.switch_to.frame('firstFr')  # 可以直接通过 id 或 name 定位
driver.switch_to.frame(0)  # 通过 iframe 的索引切换,从0开始
driver.find_element("xpath", '//input[@placeholder="Enter name"]').send_keys("fish")
driver.save_screenshot("./picture/fff_1.png")
time.sleep(2)

iframe = driver.find_element("xpath", "//iframe[@src='innerFrame']")
driver.switch_to.frame(iframe)  # 通过iframe元素定位切换
driver.find_element("name", 'email').send_keys("37857796")
driver.save_screenshot("./picture/fff_2.png")
time.sleep(2)

driver.switch_to.parent_frame()  # 回到上一层 iframe
driver.find_element("name", 'lname').send_keys("haha")
driver.save_screenshot("./picture/fff_3.png")

driver.switch_to.default_content()  # 回到默认 iframe
print(driver.find_element("xpath", "//h1[text()=' Frame']").text)

time.sleep(2)
driver.quit()

window切换

import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

option = Options()
option.page_load_strategy = "eager"
driver = webdriver.Chrome(options=option)
driver.implicitly_wait(60)
driver.get("https://letcode.in/windows")
time.sleep(2)
driver.find_element("id", "home").click()
print(driver.current_window_handle)  # 打印当前窗口名称
time.sleep(2)
handles = driver.window_handles  # 当前浏览器所有窗口
print(handles)
driver.switch_to.window(handles[-1])
print(driver.current_window_handle)
assert driver.title == "LetCode - Testing Hub"
time.sleep(3)
driver.quit()

elements多元素

import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

option = Options()
option.page_load_strategy = "eager"
driver = webdriver.Chrome(options=option)
driver.implicitly_wait(60)
driver.get("https://letcode.in/elements")
time.sleep(2)
driver.find_element("name", "username").send_keys("dd")
driver.find_element("id", "search").click()
els = driver.find_elements("xpath", "//a[@target='_blank']")
time.sleep(3)
print(type(els))
for i in els:
    print(i)
    # print(i.get_attribute("outerHTML"))
time.sleep(3)
driver.quit()

selectable多选择

import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver import ActionChains, Keys

option = Options()
option.page_load_strategy = "eager"
driver = webdriver.Chrome(options=option)
driver.implicitly_wait(60)
driver.get("https://letcode.in/selectable")
time.sleep(2)
el1 = driver.find_element("xpath", "//h3[text()='Selenium']")
el2 = driver.find_element("xpath", "//h3[text()='Appium']")
ActionChains(driver).key_down(Keys.CONTROL).click(el1).click(el2).key_up(Keys.CONTROL).perform()
time.sleep(3)
driver.quit()

drag_and_drop拖拽

import time
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.chrome.options import Options

option = Options()
option.page_load_strategy = "eager"
driver = webdriver.Chrome(options=option)
driver.implicitly_wait(60)
driver.get("https://letcode.in/dropable")
time.sleep(2)
source = driver.find_element("id", "draggable")
target = driver.find_element("id", "droppable")
ActionChains(driver).drag_and_drop(source, target).perform()  # 将元素从 source 拖拽到 target

ActionChains(driver).drag_and_drop_by_offset(el, 290, 290).perform()  # 拖动指定元素偏移(不生效,暂时找不到原因)
ActionChains(driver).click_and_hold(el).move_by_offset(290, 290).release().perform()  # 不生效,暂时找不到原因

time.sleep(3)
driver.quit()

move_to_element鼠标悬停

import time
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.chrome.options import Options

option = Options()
option.page_load_strategy = "eager"
driver = webdriver.Chrome(options=option)
driver.implicitly_wait(10)
driver.get("https://www.runoob.com/html/html-tutorial.html")
time.sleep(1)
el = driver.find_element("xpath", "//a[text()=' HTML / CSS']")
ActionChains(driver).move_to_element(el).perform()
driver.find_element("xpath", "//a[text()='HTML5 教程']").click()
assert driver.title == "HTML5 教程 | 菜鸟教程"
time.sleep(3)
driver.quit()

其他操作:

右击鼠标:context_click()

双击鼠标:double_click()

upload文件上传

import time
import keyboard  # pip install keyboard
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

option = Options()
option.page_load_strategy = "eager"
driver = webdriver.Chrome(options=option)
driver.implicitly_wait(60)
driver.get("https://letcode.in/file")
time.sleep(2)
driver.find_element("xpath", "//span[contains(text(),'Choose a file')]").click()
time.sleep(2)
keyboard.write("D:\win11专业版秘钥.txt")  # 上传文件地址
time.sleep(1)
keyboard.press("enter")  # 按 回车 键
time.sleep(3)
driver.quit()

download文件下载

import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

option = Options()
option.page_load_strategy = "eager"
# profile.default_content_settings.popups:设置为0禁止弹出窗口
# download.default_directory:设置下载路径(路径前面加转义字符r会下载失败)
prefs = {'profile.default_content_settings.popups': 0, 'download.default_directory': 'D:\code\PycharmProjects\selenium_test\picture\'}
option.add_experimental_option('prefs', prefs)
driver = webdriver.Chrome(options=option)
driver.implicitly_wait(60)
driver.get("https://letcode.in/file")
time.sleep(2)
driver.find_element("id", "xls").click()
time.sleep(3)
driver.quit()

js处理自动化

js滚动条

import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

option = Options()
option.page_load_strategy = "eager"
driver = webdriver.Chrome(options=option)
driver.get('https://www.runoob.com/')
driver.implicitly_wait(60)
time.sleep(1)

# window.scrollTo(x, y)  # 滚动条横向移动到x像素位置,纵向移动到y像素位置
# document.documentElement.scrollHeight  # 整个页面竖向滚动条像素大小
# js = "var q=document.documentElement.scrollTo=n"  # 控制滚动条竖向移动到n像素的位置

js_bottom = "window.scrollTo(0,document.documentElement.scrollHeight)"
driver.execute_script(js_bottom)  # 滚到页面最底部
time.sleep(2)

el_XQuery = driver.find_element("xpath", '//h4[text()="【学习 XQuery】"]')
js_XQuery = "arguments[0].scrollIntoView()"  # 下拉聚焦元素的位置
driver.execute_script(js_XQuery, el_XQuery)
el_XQuery.click()
time.sleep(3)
assert driver.title == "XQuery 教程 | 菜鸟教程"
driver.quit()

js处理只读控件

# 删除readonly属性
js = 'document.getElementById("id元素值").removeAttribute("readonly");'
driver.execute_script(js)
# driver.find_element_by_id("id元素值").clear()
# driver.find_element_by_id("id元素值").send_keys("2021-12-25")

js处理元素定位

有时候的定位元素就展示在页面上,但是webdriver一直无法对浏览器操作,所以需要使用js来操作

ele = driver.find_element("xpath","//div[text()='箱包']")
driver.execute_script("arguments[0].click();",ele)

driver.execute_script("return document.getElementById('id元素值').click()")

cookie操作

import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

option = Options()
option.page_load_strategy = "eager"
driver = webdriver.Chrome(options=option)
driver.implicitly_wait(10)
driver.get("https://www.runoob.com/html/html-tutorial.html")
time.sleep(1)
cookies = driver.get_cookies()  # 获取当前所有cookie信息
for cookie in cookies:
    # 值打印cookie中的name和value
    print(f"{cookie['name']} -> {cookie['value']}")
print("================================================================================")
c1 = [{'name': '.CNBlogsCookie', 'value': 'xxxx'}, {"name": "key-aaaaaaa", "value": "value-aaaaaaa"}]
for i in c1:
    driver.add_cookie(i)
cookies = driver.get_cookies()
for cookie in cookies:
    print(f"{cookie['name']} -> {cookie['value']}")
print("================================================================================")
print(driver.get_cookie("key-aaaaaaa"))  # 获取当前指定名称的cookie信息
driver.delete_cookie(".CNBlogsCookie")  # 删除当前指定名称的cookie信息
print(driver.get_cookies())
driver.delete_all_cookies()  # 删除所有的cookie信息
print("================================================================================")
print(driver.get_cookies())
time.sleep(3)
driver.quit()

Selenium自动化

框架

  • PO(Page Object):页面对象模型,它是一种设计思想,意思是,把一个页面,当做一个对象,页面的元素和元素之间操作方法就是页面对象的属性和行为。

    • 表现层(基础层BasePage):封装一些最基础的selenium原生的api方法,元素定位,框架跳转等
    • 操作层(PO层):元素定位、获得元素对象,页面动作,例如点击、输入、拖拽等
    • 业务层(测试用例层):业务逻辑,数据驱动,在页面中对若干元素操作后所实现的步骤(测试用例)

    Page Object模式是一种自动化测试设计模式,将页面定位和业务操作分开,分离测试对象(元素对象)和测试脚本(用例脚本),UI界面的改变不需要修改业务逻辑代码,只需要找到对应的PO页修改定位即可,数据代码分离,PO模式能提高代码的可读性、高复用性、可维护性。

  • Python+Selenium+Pytest+pymysql+ openpyxl+log

image-20230812142939912

常见 Selenium 异常

NoSuchElementException:没有该元素异常
TimeoutException:超时异常
ElementNotVisibleException:元素不可见异常
NoSuchAttributeException:没有这样属性异常
NoSuchFrameException:没有该frame异常

配置相关

import pathlib


class Config():
    # 当前的文件路径
    current_path = pathlib.Path(__file__).absolute()
    # root
    root = current_path.parent.parent
    # 驱动路径
    driver_path = root / "drivers/chromedriver.exe"  # 谷歌浏览器驱动位置
    # 默认等待时间
    default_timeout = 10
    # 域名
    host = "测试网站"
    # 默认加载策略
    load_strategy = "eager"
    # 用户名
    user_mobile = "手机号"
    # 密码
    passwd = "密码"

    # Database
    database = dict(host="数据库IP地址",
                    port=端口号,
                    user="用户名",
                    password="密码",
                    database="数据库")

测试夹具-驱动封装

import pytest
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from config.setting import Config
from pages.loginpages import Loginpage


@pytest.fixture()
def driver():
    driver_path = Config.driver_path  # 浏览器驱动地址
    option = Options()
    option.page_load_strategy = Config.load_strategy  # 页面加载策略
    service = Service(executable_path=driver_path)
    d = webdriver.Chrome(options=option, service=service)
    d.implicitly_wait(Config.default_timeout)  # 设置隐性等待
    yield d
    time.sleep(3)
    d.quit()


@pytest.fixture()
def login(driver):
    Loginpage(driver).login(Config.user_mobile, Config.user_passwd)
    Loginpage(driver).get_account_info(Config.user_mobile)

logging日志模块二次封装

import logging
import time
from datetime import datetime
from logging.handlers import RotatingFileHandler
from PycharmProjects.shangcheng.config.setting import Config

if not (Config.root / "logs").exists():
    (Config.root / "logs").mkdir()
logs_path = Config.root / "logs"
data = time.strftime("%Y-%m-%d_%H-%M-%S_%p", time.localtime())

class Logging():
    def __init__(self):
        self.logger = logging.getLogger('日志处理')
        self.logger.setLevel(logging.INFO)
        self.log_formatter = logging.Formatter(
            fmt="%(asctime)s,%(msecs)03d - %(levelname)s - [%(filename)s] - %(funcName)s - [line: %(lineno)d] - %(message)s",
            datefmt="%Y-%m-%d %p %H:%M:%S")

    def __create_console_handler(self):
        # self.console_handler = logging.handlers.TimedRotatingFileHandler('all.log', when='midnight', interval=1, backupCount=7, atTime=datetime.time(0, 0, 0, 0))
        self.console_handler = logging.StreamHandler()  # 默认是sys.stderr
        self.console_handler.setLevel(logging.DEBUG)
        self.console_handler.setFormatter(self.log_formatter)
        return self.console_handler

    def __create_file_handler(self):
        # self.file_handler = logging.FileHandler(logs_path / 'logs.log', encoding="utf-8")
        self.file_handler = RotatingFileHandler(filename=logs_path / f"log_{data}.log", mode="a", maxBytes=5 * 1024 * 1024, backupCount=5, encoding='utf-8')
        self.file_handler.setLevel(logging.INFO)
        self.file_handler.setFormatter(self.log_formatter)
        return self.file_handler

    def add_handler(self):
        self.__create_console_handler()
        self.__create_file_handler()
        if not self.logger.handlers:
            self.logger.addHandler(self.console_handler)
            self.logger.addHandler(self.file_handler)
        return self.logger


logger = Logging().add_handler()

Mysql数据库封装

import pymysql
from pymysql.cursors import DictCursor
from config.setting import Config


class DB:
    def __init__(self):
        self.conn = pymysql.connect(**Config.database)

    def query_one(self, sql):
        cursor = self.conn.cursor(cursor=DictCursor)
        cursor.execute(sql)
        result = cursor.fetchone()
        cursor.close()
        return result

    def query_all(self, sql):
        cursor = self.conn.cursor(cursor=DictCursor)
        cursor.execute(sql)
        result = cursor.fetchall()
        cursor.close()
        return result

    def close(self):
        """关闭数据库"""
        self.conn.close()

openpyxl封装

"""专门去操作Excel表格的"""
import openpyxl


def read_excel(file, sheet_name):
    workbook = openpyxl.load_workbook(file)
    sheet = workbook[sheet_name]
    items = list(sheet.values)
    title = items[0]
    new_list = [dict(zip(title, item)) for item in items[1:]]
    return new_list

Selenium常用操作方法

from selenium.webdriver import Chrome, ActionChains, Keys
from selenium.webdriver.support.select import Select
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


class BasePage(object):
    """把所有的浏览器常用操作都封装成现成的方法直接使用"""

    def __init__(self, driver: Chrome):
        self.driver = driver

    def goto(self, url):
        """访问URL"""
        self.driver.get(url)

    def click(self, locator):
        """封装浏览器的点击操作"""
        # el.click() locator = ("xpath", 'xxx')
        # ActionChains().click()
        el = self.driver.find_element(*locator)
        try:
            el.click()
        except:
            ActionChains(self.driver).click(el).perform()

    def send_keys(self, words, locator=None):
        # 输入
        if locator:
            el = self.driver.find_element(*locator)
            # 相当于 ActionChains 里面的 send_keys_to_element
            # 先点击元素el,再然后在输入内容,先会有光标的聚焦
            el.send_keys(words)
            return
        else:
            ActionChains(self.driver).send_keys(words).perform()

    def switch_to_frame(self, locator):
        """切换iframe"""
        iframe = self.driver.find_element(*locator)
        self.driver.switch_to.frame(iframe)

    def switch_to_window(self):
        """切换窗口"""
        handles = self.driver.window_handles
        self.driver.switch_to.window(handles[-1])

    def click_alert(self, type, word=None):
        """弹框处理"""
        alert = self.driver.switch_to.alert
        if type == "accept":
            alert.accept()
        elif type == "dismiss":
            alert.dismiss()
        elif type == "sendkeys":
            alert.send_keys(word)
            alert.accept()

    def select_by_text(self, locator, text):
        """通过值定位下拉框"""
        el = self.driver.find_element(*locator)
        Select(el).select_by_visible_text(text)

    def assert_text_equal(self, locator, expected):
        """断言元素的文本"""
        el = self.driver.find_element(*locator)
        assert el.text == expected

    def wait_element_located(self, locator):
        """等待元素出现"""
        wait = WebDriverWait(self.driver, 10)
        wait.until(EC.presence_of_element_located(locator))

    def assert_title_equal(self, expected):
        """断言当前网页的title"""
        assert self.driver.title == expected

    def double_click(self, locator):
        """双击"""
        el = self.driver.find_element(*locator)
        ActionChains(self.driver).double_click(el).perform()

    def drag_and_drop(self, locator1, locator2):
        """鼠标拖动"""
        el1 = self.driver.find_element(*locator1)
        el2 = self.driver.find_element(*locator2)
        ActionChains(self.driver).drag_and_drop(el1, el2).perform()

    def press_enter(self):
        """回车"""
        ActionChains(self.driver).send_keys(Keys.ENTER).perform()

    def copy(self):
        """复制"""
        action = ActionChains(self.driver)
        action.key_down(Keys.CONTROL).send_keys("c").key_up(Keys.CONTROL).perform()

    def paste(self):
        """粘贴"""
        action = ActionChains(self.driver)
        action.key_down(Keys.CONTROL).send_keys("v").key_up(Keys.CONTROL).perform()

    def js_click(self, locator):
        """使用js点击坐标"""
        el = self.driver.find_element(*locator)
        js = "arguments[0].click();"
        self.driver.execute_script(js, el)

    def scroll_to_element(self, locator):
        """js滚动到指定元素位置"""
        el = self.driver.find_element(*locator)
        js = "arguments[0].scrollIntoView()"
        self.driver.execute_script(js, el)

    def scroll_to_bottom(self):
        """滚动到窗口底部"""
        script = 'window.scrollTo(0, document.body.scrollHeight)'
        self.driver.execute_script(script)

posted @   暮雨星辰  阅读(65)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示