当前位置: 首页 > news >正文

web自动化框架:selenium学习使用操作大全(Python版)

目录

    • 一、浏览器驱动下载
    • 二、selenium-python安装(打开网站、操作元素)
    • 三、网页解析(HTML、xpath)
    • 四、selenium基本操作
      • 1、元素定位八种方法
      • 2、元素动态定位
      • 3、iframe切换
      • 4、填充表单_填充文本框
      • 5、填充表单_单选按钮
      • 6、填充表单_下拉列表
      • 7、切换窗口和标签页
      • 8、显式等待
      • 9、隐式等待
      • 10、警告框
      • 11、confirm确认框
      • 12、prompt提示框
      • 13、鼠标操作动作链
      • 14、执行js代码_滚动1
      • 15、执行js代码_滚动2
      • 16、上传操作_input上传
      • 17、上传操作_非input上传_pywinauto
      • 18、上传操作_非input上传_pyautogui
    • 五、selenium调整窗口大小
    • 六、判断元素是否允许被操作
    • 七、获取某个元素的html
    • 八、其他问题
      • 1、svg定位
      • 2、处理chrome显示通知弹框
      • 3、获取元素的文本
      • 4、切换网址
      • 5、find_element_by_xpath()被弃用解决方案

一、浏览器驱动下载

Selenium需要浏览器驱动程序才能与所选浏览器交互。例如,Firefox需要安装geckodriver。确保它在PATH中。

主流浏览器驱动下载地址如下:

浏览器驱动名称打开方式及注意事项地址
Chromechromedriverdriver = webdriver.Chrome()
下载浏览器对应版本的chromedriver.exe
一定要创建对象,不然打开会闪退!!!
https://registry.npmmirror.com/binary.html?path=chromedriver
Firefoxgeckodriverwebdriver.Firefox()
下载最新版本的geckodriver.exe
https://github.com/mozilla/geckodriver/releases
EdgeMicrosoftWebDriverdriver = webdriver.Edge()
最好在官网下载对应版本的浏览器:https://www.microsoft.com/en-us/edge,然后下载浏览器对应版本的msedgedriver.exe
一定要创建对象,不然打开会闪退!!!
windows10运行代码时:将msedgedriver.exe重命名为MicrosoftWebDriver.exe,不然运行程序会报错!!!
windows11运行代码时:msedgedriver.exe不要重命名!!!
https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver
IEIEDriverServerwebdriver.Ie()
下载selenium对应版本的IEDriverServer.exe
https://registry.npmmirror.com/binary.html?path=selenium

具体,可以查看:chromedriver、geckodriver、MicrosoftWebDriver、IEDriverServer和operadriver之间的恩怨纠葛

二、selenium-python安装(打开网站、操作元素)

1.安装

pip install -U selenium

注:-U就是指定下载最新版本的selenium
2. 控制浏览器
2.1 打开浏览器

from selenium import webdriver
# 打开浏览器
driver = webdriver.Chrome()

或者,可以指定驱动路径:

driver = webdriver.Chrome(executable_path=r'D:\Program Files\Python36\chromedriver.exe')

关闭浏览器及其对应驱动:

driver.quit()

还可以通过上下文来控制其执行操作后自动关闭:

with webdriver.Chrome(executable_path='chromedriver.exe') as driver:driver......

2.2 打开网站

driver.get('https://blog.csdn.net/testleaf/article/details/123269042')

延时3秒:

import time
time.sleep(3)

2.3 定位元素
传说中的八大元素定位方法:

driver.find_element_by_id()                 # 通过id属性定位(唯一);常用
driver.find_element_by_xpath()              # 通过xpath表达式定位;常用
driver.find_element_by_class_name()         # 通过类名定位;常用
driver.find_element_by_name()               # 通过name属性定位
driver.find_element_by_tag_name()           # 通过标签名定位
driver.find_element_by_css_selector()       # 通过css选择器定位
driver.find_element_by_link_text()          # 通过链接标签的text类容定位
driver.find_element_by_partial_link_text()  # 通过匹配链接标签的text类容定位

上面的都是找到第一个元素,每一个方法都有对应多个元素的方法:
如:driver.find_elements_by_id()

示例1:
driver.find_element_by_id(“toolbar-search-input”)
在这里插入图片描述
示例2:
driver.find_element_by_name(“wd”)
在这里插入图片描述
2.4 操作元素

# 定位搜索框
element = driver.find_element_by_id("toolbar-search-input")
# 输入搜索内容
element.send_keys('web自动化框架:selenium入门')
# 定位搜索按钮
search_button = driver.find_element_by_id('toolbar-search-button')
# 点击搜索按钮
search_button.click()

三、网页解析(HTML、xpath)

1.HTML
HTML【Hyper Text Markup Language】:超文本标记语言,不是编程语言,用来描述网页的。也称为:网页的源码、html源码、html文档、document。
具体,可以查看:
网页的源码,html源码,html文档,document
HTML常用标签
HTML示例:

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>Title</title><style>#table {border: 1px solid}.th {font-size: 20px}</style>
</head>
<body>
<div>我是一个div标签</div>
<h1>我是一个大<span style="color:red">标签</span></h1>
<p></p>
<a href="https://blog.csdn.net/testleaf">testleaf</a>
<table id="table"><thead><tr><th class="th aaa">字段1</th><th class="th">字段2</th><th class="th">字段3</th></tr></thead><tbody><tr><td>1</td><td>2</td><td>3</td></tr></tbody>
</table>
<form action=""><p>用户名: <input type="text"></p><p>密码:<input type="password"></p><p><input type="submit"></p>
</form>
</body>
</html>

2.xpath
xpath:一个解析html/xml的语言。

  • 语法
    • 选取节点
      • nodename 选取此节点的所有子节点
      • / 从根节点选取
      • // 从匹配选择的当前节点选择文档中的节点,不考虑它们的位置
      • . 选取当前节点
      • … 表示选取当前节点的父节点,如://div[@class="active"]/..
      • @ 选取属性
      • 案例
        • //div 获取文档中的所有的div
    • 谓语 用来查找特定的节点,或者包含指定值的节点
      • 谓语被包裹在中括号中
      • //div[@class="active"]
      • //div[@class="active" and @id="kw"]
      • //div[@class="active" or @id="kw"]
      • //div[@class="active"]/span[last()]
    • 轴 用来查找相对于当前节点的节点
      • 使用语法 轴名称::节点名称[谓语]
      • ancestor 选取当前节点的所有父辈节点
      • parent 选取当前节点的父节点
      • 如://div[@class="active"]/child::book
      • …详见 https://www.w3school.com.cn/xpath/xpath_axes.asp
    • 函数
      • text() 元素的text内容
        • //li[text()="强烈推荐"]
      • contains(@属性名/text(), value)包含的内容
        • //li[contains(@class, "ls")]

在浏览器中进行验证:

$x('//div')

在这里插入图片描述

四、selenium基本操作

Pycharm-Terminal操作:

IPYTHON
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.baidu.com')
driver.quit()
exit()

在这里插入图片描述
浏览器-Console操作:

window.scrollTo(0,100)

在这里插入图片描述

1、元素定位八种方法

传说中的八大元素定位方法:

driver.find_element_by_id()                 # 通过id属性定位(唯一);常用
driver.find_element_by_xpath()              # 通过xpath表达式定位;常用
driver.find_element_by_class_name()         # 通过类名定位;常用
driver.find_element_by_name()               # 通过name属性定位
driver.find_element_by_tag_name()           # 通过标签名定位
driver.find_element_by_css_selector()       # 通过css选择器定位
driver.find_element_by_link_text()          # 通过链接标签的text类容定位
driver.find_element_by_partial_link_text()  # 通过匹配链接标签的text类容定位

以上方法只会返回匹配到的第一个元素;
返回的是 selenium.webdriver.remote.webelement.WebElement的对象;
返回多个元素在element后加s即可,例如:driver.find_elements_by_xpath(),使用时要小心;
凡是elements的方法返回的是列表;

from selenium import webdriverdriver = webdriver.Chrome()# 打开百度页面
driver.get('https://www.baidu.com')# 1. 获取搜索框
search_input = driver.find_element_by_id('kw')
print(type(search_input))
print('1.搜索框的name属性值=', search_input.get_attribute('name'))# 2. 搜索按钮
search_btn = driver.find_element_by_xpath('//input[@value="百度一下"]')
print('2.搜索按钮的id=', search_btn.get_attribute('id'))# 3. 百度logo
logo = driver.find_element_by_class_name('index-logo-src')
print('3.百度logo的src=', logo.get_attribute('src'))# 4. 通过name属性定位搜索框
search_input_by_name = driver.find_element_by_name('wd')
print('4.搜索框的id=', search_input_by_name.get_attribute('id'))# 5. 热搜榜中的链接
hot_ul = driver.find_element_by_xpath('//ul[@id="hotsearch-content-wrapper"]')
# hot_ul = driver.find_element_by_xpath('//ul[@text()="热榜"]')
hot_a_s = hot_ul.find_element_by_tag_name('a')
print('5.热搜榜第一的标题是:', hot_a_s.text)# 6. 通过css选择器定位搜索框
search_input_by_css = driver.find_element_by_css_selector('#kw')
print('6.搜索框的name=', search_input_by_css.get_attribute('name'))# 7. 新闻栏目
el_a = driver.find_element_by_link_text('新闻')
print('7.新闻栏目的url=', el_a.get_attribute('href'))# 8. 通过部分text匹配新闻栏目
el_a1 = driver.find_element_by_partial_link_text('新')
print('8.新闻栏目的url=', el_a1.get_attribute('href'))driver.quit()

2、元素动态定位

问题:元素的定位方式不确定,可能是id,可能是xpath,需要通过不同的方式动态指定定位方法;
办法:加判断语句,不需要我们写,selenium底层定位就是这么做的;

driver.find_element(by,value)
driver.find_elements(by,value)

by: 定位方式
value: 定位表达式

import time
from selenium import webdriver
from selenium.webdriver.common.by import Bydriver = webdriver.Chrome()# 打开百度页面
driver.get('https://www.baidu.com')id_loc = 'kw'
xpath_loc = '//input[@id="kw"]'e1 = driver.find_element(By.ID, id_loc)
# send_keys往输入框输入文本
e1.send_keys('我通过id定位')
time.sleep(3)# e2 = driver.find_element(By.XPATH, xpath_loc)
e2 = driver.find_element('xpath', xpath_loc)
e2.clear()  # 清空原有内容
e2.send_keys('我通过xpath定位')time.sleep(3)
driver.quit()

3、iframe切换

当页面中包含iframe时,不能直接操作iframe中的元素,需要先切换进iframe才行;
selenium通过driver.switch_to.frame(frame_reference)来切换;
selenium切换iframe有三种方式:

  • 1.通过webelement:
    • 使用webelement进行切换是最灵活的选择,先定位到iframe然后切换到它;
  • 2.通过name或id:
    • iframe一般都会有id或name属性,则可以使用该属性进行切换,如果name或id在页面上不唯一,name将切换到找到的第一个;
  • 3.通过iframe在页面中的索引进行切换(从0开始):
    • 在浏览器console调试工具中使用window.ampInaboxIframes可以查询当前页面中的iframe;退出iframe:driver.switch_to.default_content()
import time
from selenium import webdriver# 使用with语句进行上下文管理
# 异常时也会关闭浏览器驱动
with webdriver.Chrome() as driver:driver.get('https://www.w3school.com.cn/tiy/t.asp?f=eg_html_form_radio')# 切换iframe# 1. webelement的方式# 先获取到iframeiframe = driver.find_element_by_id('iframeResult')# 再切换到driver.switch_to.frame(iframe)# 2. name/id的方式# 直接通过name/id切换driver.switch_to.frame('iframeResult')# 3. 使用索引# 切换到第二个iframetime.sleep(1)driver.switch_to.frame(1)# 找到female单选框female = driver.find_element_by_xpath('//input[@value="female"]')print(female)# 4. 离开iframe,回到主页面driver.switch_to.default_content()driver.find_element_by_xpath('//a[text()="运行代码"]')

4、填充表单_填充文本框

import time
from selenium import webdriverwith webdriver.Chrome() as driver:driver.get('https://www.baidu.com')# 搜索框定位search_input = driver.find_element_by_id('kw')# element.send_keys(string)输入文本# 所有可输入的标签都适用search_input.send_keys('软件测试')# 搜索按钮定位search_btn = driver.find_element_by_xpath('//input[@value="百度一下"]')# 点击# element.click()点击search_btn.click()time.sleep(3)

5、填充表单_单选按钮

import time
from selenium import webdriver
with webdriver.Chrome() as driver:driver.get('https://www.w3school.com.cn/tiy/t.asp?f=eg_html_form_radio')# 切换iframeiframe = driver.find_element_by_id('iframeResult')driver.switch_to.frame(iframe)# 找到female单选框female = driver.find_element_by_xpath('//input[@value="female"]')# 在元素上点击female.click()  # 选中time.sleep(5)

6、填充表单_下拉列表

下拉框有两种处理方法:
(1)直接定位到要选中的option选项,然后点击
(2)通过selenium.webdriver.support.ui.Select类

import time
from selenium import webdriver
from selenium.webdriver.support.ui import Selectwith webdriver.Chrome() as driver:driver.get('https://www.w3school.com.cn/tiy/t.asp?f=eg_html_elements_select')# 切换iframeiframe = driver.find_element_by_id('iframeResult')driver.switch_to.frame(iframe)# 找到audi选项# 1. 通过option直接操作option = driver.find_element_by_xpath('//option[@value="audi"]')option.click()time.sleep(1)# 2. 通过select类# 找到selectselect = Select(driver.find_element_by_xpath('//select[@name="cars"]'))## # 选中索引为1的选项,索引从0开始select.select_by_index(1)time.sleep(1)## # 选中value等于audi的选项select.select_by_value('audi')time.sleep(1)## # 选中option的文本为Volvo的选项select.select_by_visible_text('Volvo')time.sleep(3)

7、切换窗口和标签页

webdriver 不区分窗口和标签页。打开一个新的标签页或者窗口,selenium会使用窗口句柄来处理它。
每个窗口都有一个唯一的标识符,该标识符在单个会话中保持持久性。
(1)获取当前窗口句柄:driver.current_window_handle
(2)切换窗口或标签页:通过循环遍历的方式来切换;

import time
from selenium import webdriver
with webdriver.Chrome() as driver:driver.get('https://www.baidu.com')# 找到搜索框search_input = driver.find_element_by_id('kw')search_input.send_keys('图片')# 点击搜索按钮driver.find_element_by_id('su').click()time.sleep(1)# 获取原窗口的handleoriginal_window = driver.current_window_handleprint('当前窗口句柄', original_window)print('窗口的title', driver.title)# 选取第一个结果并点击driver.find_element_by_xpath('//div[@id="3001"]//a').click()# time.sleep(1)for handle in driver.window_handles:if handle != original_window:# 切换到新窗口driver.switch_to.window(handle)break# 打印当前窗口句柄print('新打开的搜索页面句柄', driver.current_window_handle)print('新打开的页面的title', driver.title)time.sleep(5)

8、显式等待

浏览器渲染页面的时候需要时间,如果没有渲染完成就对元素进行定位将会找不到到该元素;
所以需要加延时进行等待,有三种等待方式:
(1)time.sleep()
前面已经反复使用了;等待时间固定,不稳定;等待时间多半不确定;

(2)显式等待
显式等待就是在元素操作前循环判断操作的条件是否满足,满足后再操作;
selenium通过selenium.webdriver.support.ui.WebDriverWait类的对象来实现显式等待;webDriverWait类实例化时可以接收3个参数:

  • driver: webdriver对象
  • timeout:超时时间,最多等待多少秒
  • poll_frequency: 检查频率,默认0.5秒

until方法接受1个参数:

  • conditions:条件在selenium.webdriver.support.expected_conditions 模块中;
    常见条件:
    presence_of_element_located:元素存在于dom中
    visibility_of_element_located:元素可见
    element_to_be_clickable:元素可点击
    element_to_be_selected:元素可选择

实例化条件需要传入一个定位参数,是一个二元元组:(by, loc_expression)

import time
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
import selenium.webdriver.support.expected_conditions as ECwith webdriver.Chrome() as driver:driver.get('https://www.baidu.com')# 找到搜索框search_input = driver.find_element_by_id('kw')search_input.send_keys('图片')# 点击搜索按钮driver.find_element_by_id('su').click()# 获取原窗口的idoriginal_window = driver.current_window_handleprint('当前窗口句柄', original_window)print('窗口的title', driver.title)# 选取第一个结果并点击## WebDriverWait(driver, timeout=3).until(#     EC.visibility_of_element_located((By.XPATH, '//div[@id="3001"]//a'))# ).click()s_time = time.time()btn = WebDriverWait(driver, timeout=3).until(EC.visibility_of_element_located((By.ID, '3001')))btn.click()e_time = time.time()print(e_time-s_time)# WebDriverWait(driver, timeout=3).until(#     EC.visibility_of_element_located(('id', '3001'))# ).click()# 会等待id为3001的元素可见,timeout=3表示最多等待3秒钟,超时就抛出异常# driver.find_element_by_xpath('//div[@id="3001"]//a').click()# time.sleep(1)for handle in driver.window_handles:if handle != original_window:# 切换到新窗口driver.switch_to.window(handle)break# 打印当前窗口句柄print('新打开的搜索页面句柄', driver.current_window_handle)print('新打开的页面的title', driver.title)time.sleep(5)

9、隐式等待

(3)隐式等待
隐式等待本质上是设置了一个全局等待时间,WebDriver在试图查找任何元素时都会轮询一定时间,默认情况下隐式等待是禁用的。
警告:不要混用隐式等待和显示等待,这样会导致不可预测的等待时间。
例如:隐式等待设置10秒,显式等待设置15秒,可能导致在20秒后发生超时;
隐式等待是告诉WebDriver如果在查找一个或多个不是立即可用的元素时轮询DOM一段时间。默认设置为0,表示禁用。一旦设置好,隐式等待就会被设置为会话的生命周期。

import time
from selenium import webdriverwith webdriver.Chrome() as driver:# 设置隐式等待5秒driver.implicitly_wait(5)driver.get('https://www.baidu.com')# 找到搜索框search_input = driver.find_element_by_id('kw')search_input.send_keys('图片')# 点击搜索按钮driver.find_element_by_id('su').click()# 获取原窗口的idoriginal_window = driver.current_window_handleprint('当前窗口句柄', original_window)print('窗口的title', driver.title)# 选取第一个结果并点击driver.find_element_by_xpath('//div[@id="3001"]//a').click()for handle in driver.window_handles:if handle != original_window:# 切换到新窗口driver.switch_to.window(handle)break# 打印当前窗口句柄print('新打开的搜索页面句柄', driver.current_window_handle)print('新打开的页面的title', driver.title)time.sleep(5)

10、警告框

WebDriver提供了一个API,用于处理JavaScript提供的三种类型的原生弹窗消息
(1)Alerts警告框

import time
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ECwith webdriver.Chrome() as driver:driver.get('https://www.w3school.com.cn/tiy/t.asp?f=js_alert')driver.switch_to.frame('iframeResult')button = WebDriverWait(driver, timeout=3).until(EC.visibility_of_element_located(('xpath', '//button')))# 有时候需要结合sleep来处理# time.sleep(1)button.click()# time.sleep(3)# 等待alert弹出alert = WebDriverWait(driver, timeout=3).until(EC.alert_is_present())# time.sleep(1)# alert = driver.switch_to.alert# 获取弹出框文本text = alert.textprint(text)time.sleep(1)# # 确认alert.accept()time.sleep(1)

11、confirm确认框

(2) confirm确认框
与警告框不同,确认框还有取消按钮;

import time
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ECwith webdriver.Chrome() as driver:driver.get('https://www.w3school.com.cn/tiy/t.asp?f=js_confirm')driver.switch_to.frame('iframeResult')button = WebDriverWait(driver, timeout=3).until(EC.visibility_of_element_located(('xpath', '//button')))button.click()# # 等待confirm弹出WebDriverWait(driver, timeout=3).until(EC.alert_is_present())## # 获取alertalert = driver.switch_to.alert## # 获取弹出框文本text = alert.textprint(text)time.sleep(2)# # 取消# 点击取消后 当前的alert对象就会被销毁alert.dismiss()# alert.accept() 确认time.sleep(2)

12、prompt提示框

(3)prompt提示框
还可以输入文本;

import time
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
with webdriver.Chrome() as driver:driver.get('https://www.w3school.com.cn/tiy/t.asp?f=js_prompt')driver.switch_to.frame('iframeResult')button = WebDriverWait(driver, timeout=3).until(EC.visibility_of_element_located(('xpath', '//button')))# 避免js没有绑定出现意外问题,加一秒延时time.sleep(1)button.click()# 等待alert弹出WebDriverWait(driver, timeout=3).until(EC.alert_is_present())# 获取alertalert = driver.switch_to.alert# 输入信息alert.send_keys('testleaf')time.sleep(3)# 确认alert.accept()# alert.dismiss() 取消time.sleep(3)

13、鼠标操作动作链

鼠标是通过使用底层接口执行的,需要调用ActionChains对象来执行对应的方法。
(1)clickAndHold:它将移动到该元素,然后在给定元素的中间单击(不释放);
(2)contextClick:此方法首先将鼠标移动到元素的位置, 然后在给定元素执行上下文点击(右键单击);
(3)doubleClick:它将移动到该元素, 并在给定元素的中间双击;
(4)moveToElement:此方法将鼠标移到元素的中间. 执行此操作时, 该元素也会滚动到视图中;
(5)moveByOffset:此方法将鼠标从其当前位置(或0,0)移动给定的偏移量. 如果坐标在视图窗口之外, 则鼠标最终将在浏览器窗口之外;
(6)dragAndDrop:此方法首先在源元素上单击并按住,然后移动到目标元素的位置后释放鼠标;
(7)release:此操作将释放按下的鼠标左键. 如果WebElement转移了, 它将释放给定WebElement上按下的鼠标左键;

import time
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ECwith webdriver.Chrome() as driver:driver.get(r'file://D:\project\action.html')div = WebDriverWait(driver, timeout=3).until(EC.visibility_of_element_located(('xpath', '//div[@οnmοuseοver="mOver(this)"]')))# 移动到指定元素 move_to_elementwebdriver.ActionChains(driver).move_to_element(div).perform()time.sleep(2)# 移开多大位置x,y move_by_offsetwebdriver.ActionChains(driver).move_by_offset(xoffset=500, yoffset=500).perform()time.sleep(2)# 点住不放 click_and_holddiv = driver.find_element_by_xpath('//div[@οnmοusedοwn="mDown(this)"]')webdriver.ActionChains(driver).click_and_hold(div).perform()time.sleep(2)# 松开鼠标 releasewebdriver.ActionChains(driver).release(div).perform()time.sleep(2)# double_click 双击button = driver.find_element_by_xpath('//button[@ondblclick]')webdriver.ActionChains(driver).double_click(button).perform()time.sleep(2)# drag 将div1拖拽到div2上div1 = driver.find_element_by_id('draggable')div2 = driver.find_element_by_id('droppable')webdriver.ActionChains(driver).drag_and_drop(div1, div2).perform()time.sleep(3)# contextClick 点击鼠标右键div = driver.find_element_by_xpath('//div[@οnmοusedοwn="whichButton(event)"]')webdriver.ActionChains(driver).context_click(div).perform()time.sleep(2)

14、执行js代码_滚动1

selenium执行js有几个方法,这里我们使用最常用的方法execute_script;

import time
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ECwith webdriver.Chrome() as driver:driver.get('https://image.baidu.com')search_input = WebDriverWait(driver, 3).until(EC.visibility_of_element_located(('id', 'kw')))search_input.send_keys('软件测试')WebDriverWait(driver, 3).until(EC.element_to_be_clickable(('xpath', '//input[@value="百度一下"]'))).click()time.sleep(3)# 滚动到(0px,100px)的位置driver.execute_script("window.scrollTo(0,100)")time.sleep(1)driver.execute_script("window.scrollTo(0,200)")time.sleep(1)driver.execute_script("window.scrollTo(0,300)")time.sleep(3)# 移动到底部driver.execute_script("window.scrollTo(0,document.body.scrollHeight)")time.sleep(3)# 移动到顶部driver.execute_script("window.scrollTo(0,0)")time.sleep(3)

15、执行js代码_滚动2

selenium执行js有几个方法,这里我们使用最常用的方法execute_script
执行js时,还可以传递参数给js脚本;
下面的案例:
打开页面,并滚动到指定的元素可见为止;
下面的代码 div 被传递给了arguments,通过切片的方式可以取出;

import time
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ECwith webdriver.Chrome() as driver:driver.get(r'file://D:\project\scroll.html')time.sleep(2)div = driver.find_element_by_xpath('//div')# 移动到元素的底端与当前窗口的底部对齐driver.execute_script("arguments[0].scrollIntoView(false);", div)time.sleep(2)# 移动到元素的顶端与当前窗口的顶端对齐driver.execute_script("arguments[0].scrollIntoView();", div)time.sleep(2)

16、上传操作_input上传

selenium只支持input元素的上传,直接使用send_keys将文件绝对地址写入元素即可;

import time
from selenium import webdriverwith webdriver.Chrome() as driver:driver.get('https://www.baidu.com')span = driver.find_element_by_xpath('//span[@class="soutu-btn"]')span.click()time.sleep(1)input = driver.find_element_by_xpath('//input[@class="upload-pic"]')input.send_keys(r'D:\project\find.jpg')# 有可能还需要提交的操作,百度是不需要time.sleep(10)

17、上传操作_非input上传_pywinauto

很多时候页面不是使用input来进行文件上传,这是就需要通过其他第三方包来操作系统界面;
(1)pywinauto
缺点: 只能在windwows上使用;
优点:可以选择多个文件,路径中有中文也可以;

import timefrom selenium import webdriver
from pywinauto.keyboard import send_keyswith webdriver.Chrome() as driver:driver.get('https://www.baidu.com')span = driver.find_element_by_xpath('//span[@class="soutu-btn"]')span.click()time.sleep(1)# select_span = driver.find_element_by_xpath('//span[text()="选择文件"]')select_span = driver.find_element_by_xpath('//div[@class="upload-wrap"]')# 点击打开选择文件窗口select_span.click()time.sleep(3)# 选择文件send_keys(r'D:\project\find.jpg')time.sleep(1)# # 选择确定send_keys('{ENTER}')time.sleep(10)

18、上传操作_非input上传_pyautogui

很多时候页面不是使用input来进行文件上传,这里就需要通过其他第三方包来操作系统界面;
(2)pyautogui
缺点: 只能选择一个文件,文件路径有中文会出问题;
优点:跨平台(windows,mac,linux);

import timefrom selenium import webdriver
import pyautoguiwith webdriver.Chrome() as driver:driver.get('https://www.baidu.com')span = driver.find_element_by_xpath('//span[@class="soutu-btn"]')span.click()time.sleep(1)# select_span = driver.find_element_by_xpath('//span[text()="选择文件"]')select_span = driver.find_element_by_xpath('//div[@class="upload-wrap"]')# 点击打开选择文件窗口select_span.click()time.sleep(3)# 选择文件pyautogui.write(r"D:\project\find.jpg")time.sleep(1)# 选择确定pyautogui.press('enter', 2)time.sleep(10)

五、selenium调整窗口大小

selenium调整窗口到指定大小:

driver.set_window_size(900,1000)

浏览器最大化:

driver.maximize_window() 

六、判断元素是否允许被操作

driver.find_element_by_name("XXX").is_enabled() # 是否可以编辑,或者按钮是否可以点击driver.find_element_by_name("XXX").is_displayed() # 判断元素是否显示element=driver.find_element_by_name("XXX").is_selected() # 判断元素是否选中状态

七、获取某个元素的html

driver.find_element_by_id('XXX').get_attribute('innerHTML')

八、其他问题

1、svg定位

问题描述:
使用xpath方法对svg下元素进行定位,会发现无法定位到svg下的元素:

driver.find_element(xpath,"/html/body/div[19]/svg")

解决方法1【错误】:
从svg元素开始,下面的元素都要以*[name()=‘svg element’] 这种形式进行编写

driver.find_element(xpath,"/html/body/div[19]/*[name()='svg']/*[name()='path']")

会发现仍然定位不到;
解决办法2【正确】:
绝对路径的话,*[name()='svg']前面得加双斜杠,不然定位不到:

driver.find_element(xpath,"/html/body/div[19]//*[name()='svg']")

相对路径的话,*[name()='svg']前就不用加双斜杠,只用单斜杠:

driver.find_element(xpath,"//*[@id='userinfo']/*[name()='svg']/*[name()='use']")

2、处理chrome显示通知弹框

使用chrome打开weibo.com会出现以下界面的弹出框:
在这里插入图片描述

这东西不属于页面alert弹框,而是属于浏览器的设置项。

要关掉它,需要对浏览器进行属于配置。具体见下面脚本:

from selenium import webdriveroptions = webdriver.ChromeOptions()
prefs = {'profile.default_content_setting_values':{'notifications':2}
}
options.add_experimental_option('prefs',prefs)
driver = webdriver.Chrome(options = options)
driver.get("https://blog.csdn.net/testleaf/article/details/123269042")

3、获取元素的文本

element.text
get_attribute(“textContent”)
优点:可以获取隐藏元素的文本
缺点:IE不支持;获取有些元素的文本时,结果中带有空字符串;(没有尝试过)
get_attribute("innerText")
优点:可以获取隐藏元素的文本
缺点:FireFox不支持;(每个博客能搜到的都说这个缺点,但实际操作发现可以获取到每次所需的文本)

4、切换网址

直接进行切换就可以了,如下:

driver.get('https://blog.csdn.net/testleaf/article/details/123269042')
time.sleep(2)
driver.get('https://blog.csdn.net/testleaf/article/details/123302863')

5、find_element_by_xpath()被弃用解决方案

from selenium.webdriver.common.by import By
from selenium import webdriver
driver = webdriver.Chrome() #启动chromedriver
driver.get('http://www.baidu.com') #打开http://www.baidu.com
driver.find_element(By.XPATH,'//div[@class="detail-item-ctn"][1]').click() #点击按钮

免责声明:
1.编写此文是为了更好地学习selenium的使用,如果损害了有关人的利益,请联系删除;
2.如果文中描述欠妥,请在评论中进行指正;
3.文字编写不易,若感觉有用,点赞收藏关注会让博主很开心哦;
4.此外,本文支持任何形式的转载,转载请注明出处,非常感谢!!!
本文源自:https://blog.csdn.net/testleaf/article/details/123269042

相关文章:

web自动化框架:selenium学习使用操作大全(Python版)

目录 一、浏览器驱动下载二、selenium-python安装&#xff08;打开网站、操作元素&#xff09;三、网页解析&#xff08;HTML、xpath&#xff09;四、selenium基本操作1、元素定位八种方法2、元素动态定位3、iframe切换4、填充表单_填充文本框5、填充表单_单选按钮6、填充表单_…...

boringssl EVP_aes_128_ecb实现

最近学习boringssl&#xff0c;发现没找到EVP_aes_128_ecb在哪里实现的 饶了一大圈&#xff0c;发现它的定义很无语 #define EVP_CIPHER_FUNCTION(keybits, mode) \const EVP_CIPHER *EVP_aes_##keybits##_##mode(void) { \return aes_##keybits##_##mode##_gene…...

vxe-table中树形结构

如图&#xff0c;同事让帮忙实现一个需求 从二级树节点开始&#xff0c;同时选中的只能有一个二级树节点&#xff0c;选中的二级树节点之下的子节点都可以被选中。否则不能被选中 直接上代码 需要注意的是&#xff0c;文中树状图传递的数据是打平的数据&#xff0c;设置代码是…...

Linux命令查看CPU、内存、IO使用情况简单介绍

文章目录 1. CPU相关介绍1.1 物理CPU1.2 物理CPU内核1.3 逻辑CPU1.4 几核几线程1.5 CPU设计图 2. top 查看系统负载、CPU使用情况2.1 系统整体的统计信息2.2 进程信息2.3 top命令使用 3. lscpu 显示有关 CPU 架构的信息4. free 查看内存信息5. iostat 查看io信息 1. CPU相关介绍…...

RPC框架的核心是什么

文章目录 什么是 RPC封装的艺术&#xff08;如何隐藏底层逻辑&#xff09;协议的实现序列化和反序列化&#xff08;编解码&#xff09;总结 什么是 RPC 首先思考这样一个问题&#xff0c;假设你不知道任何框架&#xff0c;现在有两台机器&#xff0c;每台机器上有一个服务&…...

直播、AI赋能,美团披着荆棘前行

随着互联网流量红利逐渐消退&#xff0c;阿里、抖音、腾讯、拼多多、快手、小红书等各赛道玩家&#xff0c;为了寻求新的增量&#xff0c;纷纷“卷”向本地生活&#xff0c;开始入侵美团的腹地。然而&#xff0c;哪怕巨头环伺&#xff0c;美团仍然展现出了其独特的竞争力&#…...

提升代码逻辑的感觉——python循环语句

提升代码逻辑的感觉——python循环语句 简介 循环是编程中的一个非常重要的概念&#xff0c;它用于处理重复性任何和迭代草错&#xff0c;通过循环我们能优化并简化代码&#xff0c;提高代码的可维护性&#xff0c;在Python中循环是一种控制结构&#xff0c;允许我们重复执行…...

【ARM Coresight 系列文章 20 -- linux perf 与 ARM coresight】

文章目录 1.1 Perf Introduction1.1.1 Perf 架构图1.1.2 Perf Tools 介绍1.1.3 Perf 命令介绍1.2 Events1.2.1 Perf 与 PMU 的关系1.2.2 Hardware events1.2.1.1 linux perf 事件分类1.2.2 Software Events1.2.3 Tracepoint Events1.3 Perf 工具使用1.4 用户态开发1.4.1 用户态…...

微服务之Nacos

1 版本说明 官网地址&#xff1a; https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E 1.1 2021.x 分支 适配 SpringBoot 2.4, Spring Cloud 2021.x 版本及以上的Spring Cloud Alibaba 版本如下表&#xff08;最新版本用*标记&am…...

jvm 新生代的区域划分

虚拟机将内存分为一块较大的 Eden 空间和两块较小的 Survivor 空间&#xff0c;每次分配内存只使用 Eden 和其中一块 Survivor。发生垃圾收集时&#xff0c;将 Eden 和 Survivor 中仍然存活的对象一次性复制到另外一块 Survivor 空间上&#xff0c;然后直接清理掉 Eden 和已用过…...

【C++】对于string的补充(成员函数c_str()、大小写转换、字符串和实数之间的相互转换)

前言 本篇文章记录的是一些关于string的补充说明 string与const char*之间的相互转换 const char* 转换成string 在C中存在着从const char到string的隐式类型转换&#xff0c;换句话说&#xff0c;如果一个函数的参数类型是string类&#xff0c;直接传入const char类型的参…...

华为OD机试真题【羊狼农夫过河】

1、题目描述 【羊、狼、农夫过河】 羊、狼、农夫都在岸边&#xff0c;当羊的数量小于狼的数量时&#xff0c;狼会攻击羊&#xff0c;农夫则会损失羊。农夫有一艘容量固定的船&#xff0c;能够承载固定数量的动物。要求求出不损失羊情况下将全部羊和狼运到对岸需要的最小次数。…...

【线性代数-3Blue1Brown】- 5 三维空间的线性变换

飞书原文档&#xff1a;Docs...

Maven入门教程(二):idea/Eclipse使用Maven

Maven入门教程(一)&#xff1a;安装Maven环境 4.开发工具配置 4.1 idea配置 idea有多个版本&#xff0c;配置是一样的&#xff0c;只是配置页面的入口不一样 旧版idea 新版idea 4.2 Eclipse配置 打开Eclipse&#xff0c;菜单中选择&#xff1a;Window -> Preference ->…...

【MySQL】MySQL里的用户账户和角色是什么?如何管理?

用户&#xff08;user&#xff09;验证和授权创建用户账户连接服务器查看用户账户设置 角色&#xff08;role&#xff09;创建角色 操作用户帐户和角色重命名删除 感谢 &#x1f496; 用户&#xff08;user&#xff09; 在MySQL中&#xff0c;用户是数据库访问的主要实体。每个…...

vbs病毒

vbs脚本:VBS脚本病毒原理分析和防范 疯狂代码 http://CrazyCoder.cn/ Sh t t p : / C r a z y C o d e r . c n / S e c u r i t y / Ar t i c l e 7 2 0 0 8 . h t m l 网络流行让我们世界变得更加美好但它也有让人不愉快时候当您收到封主题为1LoveYou” 邮件用兴奋 得几乎快发…...

用Java实现Huffman编码

文章目录 前言一、实现思路二、准备Huffman结点三、主要实现 前言 在使用http1.1协议传输数据的时候&#xff0c;会有一些固定的字段&#xff0c;比如cookie、编码方式、接收的数据类型&#xff0c;另外会有一些大量重复的字段造成请求报文过于冗长&#xff0c;为了解决这个问…...

day-04 基于UDP的服务器端/客户端

一.理解UDP &#xff08;一&#xff09;UDP套接字的特点 UDP套接字具有以下特点&#xff1a; 无连接性&#xff1a;UDP是一种无连接的协议&#xff0c;这意味着在发送数据之前&#xff0c;不需要在发送方和接收方之间建立连接。每个UDP数据包都是独立的&#xff0c;它们可以独…...

FFmpeg rtp rtp_mpegts的区别

rtp 在FFmpeg中&#xff0c;rtpenc是一个用于将音视频数据封装成RTP&#xff08;Real-time Transport Protocol&#xff09;数据包并发送到网络上的编码器。RTP是一种用于实时传输音视频数据的协议&#xff0c;常用于视频会议、流媒体等场景。 rtpenc可以将音视频数据封装成R…...

【链表OJ】相交链表 环形链表1

前言: &#x1f4a5;&#x1f388;个人主页:​​​​​​Dream_Chaser&#xff5e; &#x1f388;&#x1f4a5; ✨✨刷题专栏:http://t.csdn.cn/UlvTc ⛳⛳本篇内容:力扣上链表OJ题目 目录 一.leetcode 160. 相交链表 1.问题描述: 2.解题思路: 二.leetcode 141.环形链表 …...

DevOps之自动化测试

什么是自动化测试&#xff1f; 明确一下自动化测试不是什么。自动化测试不是指自动化生成测试代码&#xff0c;而是自动化地执行由开发人员或测试人员编写的测试代码。正如下面这句谚语&#xff1a;“绝不要手工去做任何可以被自动化处理的事情。——Curt Hibbs” 之前是由人…...

Java 程序打印 OpenCV 的版本

我们可以使用 Java 程序来使用 OpenCV。 OpenCV 的使用需要动态库的加载才可以。 加载动态库 到 OpenCV 的官方网站上下载最新的发布版本。 Windows 下载的是一个可执行文件&#xff0c;没关系&#xff0c;这个可执行文件是一个自解压程序。 当你运行以后会提示你进行解压。…...

ChatGPT⼊门到精通(2):ChatGPT 能为我们做什么

⼀、雇佣免费的⼲活⼩弟 有了ChatGPT后&#xff0c;就好⽐你有了好⼏个帮你免费打⼯的「⼩弟」&#xff0c;他们可以帮你做很多 ⼯作。我简单总结⼀些我⽬前使⽤过的⽐较好的基于ChatGPT的服务和应⽤。 1、总结、分析 当我们在阅读⼀些⽂章和新闻的时候&#xff0c;有的⽂章写…...

线程和进程的区别是什么?

线程(Thread)和进程(Process)是操作系统中两个重要的概念,用于管理程序的执行。它们有以下区别: 定义:进程:进程是程序的一个执行实例,它包含了程序的代码、数据以及执行上下文。进程是操作系统分配资源和调度的基本单位。线程:线程是进程的子执行单元,一个进程可以…...

力扣27.移除元素

27. 移除元素 提示 简单 1.9K 相关企业 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序…...

指针(个人学习笔记黑马学习)

1、指针的定义和使用 #include <iostream> using namespace std;int main() {int a 10;int* p;p &a;cout << "a的地址为&#xff1a;" << &a << endl;cout << "a的地址为&#xff1a;" << p << endl;…...

vue 路由动态加载

在 Vue.js 中&#xff0c;可以使用 webpack 的动态导入语法来实现路由动态加载。下面是一个简单的示例&#xff1a; const Home () > import(/* webpackChunkName: "home" */ ./views/Home.vue); const About () > import(/* webpackChunkName: "about…...

电脑识别不了固态硬盘怎么办?

在使用固态硬盘时&#xff0c;可能会出现电脑无法识别的情况&#xff0c;这时我们就无法使用固态硬盘中的数据。那么&#xff0c;电脑识别不了固态硬盘怎么办&#xff1f; 为什么电脑识别不了固态硬盘&#xff1f; 一般来说&#xff0c;电脑识别不了固态硬盘是因为以下3个原因…...

QCustomPlot 绘制卡顿问题

大数据量导致曲线绘制卡顿问题 这里提供一个思路在跟踪源码中发现底层卡顿在vector的resize() 此处扩容中 所以尽量使用下面的接口 /*! \overloadAdds the provided data point as \a key and \a value to the current data.Alternatively, you can also access and modify t…...

uni-app开发小程序,radio单选按钮,点击可以选中,再次点击可以取消

一、实现效果&#xff1a; 二、代码实现&#xff1a; 不适用官方的change方法&#xff0c;自己定义点击方法。 动态判断定义的值是否等于遍历的值进行回显&#xff0c;如果和上一次点击的值一样&#xff0c;就把定义的值改为null <template><view><radio-group&…...

【Qt专栏】实现单例程序,禁止程序多开的几种方式

目录 一&#xff0c;简要介绍 二&#xff0c;实现示例&#xff08;Windows&#xff09; 1.使用系统级别的互斥机制 2.通过共享内存&#xff08;进程间通信-IPC&#xff09; 3.使用命名互斥锁&#xff08;不推荐&#xff09; 4.使用文件锁 5.通过网络端口检测 一&#xf…...

力扣26. 删除有序数组中的重复项

给你一个 升序排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。 考虑 nums 的唯一元素的数量为 k &#xff0c;你需要做…...

【机器学习】鸢尾花分类-逻辑回归示例

这段代码是一个完整的示例&#xff0c;展示了如何使用逻辑回归对鸢尾花数据集进行训练、保存模型&#xff0c;并允许用户输入数据进行预测。以下是对这段代码的总结&#xff1a;功能&#xff1a; 这段代码演示了如何使用逻辑回归对鸢尾花数据集进行训练&#xff0c;并将训练好的…...

Flink CDC介绍

1.CDC概述 CDC&#xff08;Change Data Capture&#xff09;是一种用于捕获和处理数据源中的变化的技术。它允许实时地监视数据库或数据流中发生的数据变动&#xff0c;并将这些变动抽取出来&#xff0c;以便进行进一步的处理和分析。 传统上&#xff0c;数据源的变化通常通过…...

Java集合sort排序报错UnsupportedOperationException处理

文章目录 报错场景排查解决UnmodifiableList类介绍 报错场景 我们使用的是PostgreSQL数据库&#xff0c;存储业务数据&#xff0c;业务代码使用的是Spring JPA我们做的是智慧交通信控平台&#xff0c;有个功能是查询展示区域的交通态势&#xff0c;需要按照不同维度排序展示区…...

安防监控/磁盘阵列存储/视频汇聚平台EasyCVR调用rtsp地址返回的IP不正确是什么原因?

安防监控/云存储/磁盘阵列存储/视频汇聚平台EasyCVR可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有GB28181、RTSP/Onvif、RTMP等&#xff0c;以及厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等&#xff0c;能对外分发RTSP、RT…...

Spring boot开启定时任务

Cron表达式生成器 基于接口的方式 使用Scheduled 注解很方便&#xff0c;但缺点是当我们调整了执行周期的时候&#xff0c;需要重启应用才能生效&#xff0c;这多少有些不方便。为了达到实时生效的效果&#xff0c;那么可以使用接口来完成定时任务&#xff0c;统一将定时器信…...

package.json相关知识记录

一、相关字段 npm官方字段介绍 &#x1f367; bin   >   简单理解&#xff1a;指定命令的名称及路径   &#x1f349; 相当于想path中添加路径&#xff0c;局部安装是在./node_modules/.bin/&#xff0c;全局安装是在全局的bin目录   &#x1f349; bin指定的文件必须…...

VueRouter使用详解(5000字通关大全)

Vue Router是一个官方的路由管理器&#xff0c;它可以让我们在Vue应用中实现单页面应用&#xff08;SPA&#xff09;的效果&#xff0c;即通过改变URL而不刷新页面来显示不同的内容。Vue Router可以让我们定义多个路由&#xff0c;每个路由对应一个组件&#xff0c;当URL匹配到…...

vue axios实现下载文件及responseType:blob注意事项

需要使用axios和js-file-download组件 npm install js-file-download --save npm install axios --save import fileDownload from fileDownload; // 引入fileDownload import axios from axios; // 引入axios axios({method: get,url: xxxxxxx,responseType: blob }).then(r…...

StringBuilder类分享(1)

一、StringBuilder说明 StringBuilder是一个可变的字符序列。这个类提供了一个与StringBuffer兼容的API&#xff0c;但不保证同步&#xff0c;即StringBuilder不是线程安全的&#xff0c;而StringBuffer是线程安全的。显然&#xff0c;StringBuilder要运行的更快一点。 这个类…...

Qt 打开文件列表选择文件,实现拖拽方式打开文件

1. 实现打开文件列表选择文件 1.1. 创建 Qt 工程&#xff0c;并添加几个简单控件 这里笔者选用的是 QMainWindow&#xff0c;创建好工程后在 ui 界面设计中添加 QLineEdit、QPushBtton至少这两个控件&#xff0c;如下图摆放。 1.2. 头文件中添加相关操作 在 mainwindow.h 中…...

[C/C++]天天酷跑游戏超详细教程-上篇

个人主页&#xff1a;北海 &#x1f390;CSDN新晋作者 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏✨收录专栏&#xff1a;C/C&#x1f91d;希望作者的文章能对你有所帮助&#xff0c;有不足的地方请在评论区留言指正&#xff0c;大家一起学习交流&#xff01;&#x1f9…...

5G NR:RACH流程 -- Msg1之选择正确的PRACH时频资源

PRACH的时域资源是如何确定的 PRACH的时域资源主要由参数“prach-ConfigurationIndex”决定。拿着这个参数的取值去协议38211查表6.3.3.2-2/3/4&#xff0c;需要注意根据实际情况在这三张表中进行选择&#xff1a; FR1 FDD/SULFR1 TDDFR2 TDD Random access preambles can onl…...

在vue3项目中编辑的时候,解决对话框里边的数据和列表中的数据联动了。深复制

//分析原因是从列表中拿到的数据直接复制去修改就涉及到堆里变的内容是一样的&#xff0c;直接复制其实只是把引用地址赋值给变量了&#xff0c;解决方法是 浅复制和深复制。<!-- 审批流程管理 --> <template><div style"float: left; width: 250px;backgr…...

循环结构(个人学习笔记黑马学习)

while循环语句 在屏幕中打印0~9这十个数字 #include <iostream> using namespace std;int main() {int i 0;while (i < 10) {cout << i << endl;i;}system("pause");return 0; } 练习案例: 猜数字 案例描述:系统随机生成一个1到100之间的数字&…...

ceph中PGLog处理流程

正文 struct pg_log_entry_t {ObjectModDesc mod_desc; //用于保存本地回滚的一些信息&#xff0c;用于EC模式下的回滚操作bufferlist snaps; //克隆操作&#xff0c;用于记录当前对象的snap列表hobject_t soid; …...

macOS使用命令行连接Oracle(SQL*Plus)

Author: histonevonzohomail.com Date: 2023/08/25 文章目录 SQL\*Plus安装下载环境配置 SQL\*Plus远程连接数据库参考文献 原文地址&#xff1a;https://histonevon.top/archives/oracle-mac-sqlplus数据库安装&#xff1a;Docker安装Oracle数据库 (histonevon.top) SQL*Plus…...

Mac下使用Homebrew安装MySQL5.7

Mac下使用Homebrew安装MySQL5.7 1. 安装Homebrew & Oh-My-Zsh2. 查询软件信息3. 执行安装命令4. 开机启动5. 服务状态查询6. 初始化配置7. 登录测试7.1 终端登录7.2 客户端登录 参考 1. 安装Homebrew & Oh-My-Zsh mac下如何安装homebrew MacOS安装Homebrew与Oh-My-Zsh…...

centos安装Nginx配置Nginx

1. 查看操作系统有没有安装Nginx which nginx 2. 使用epel的方式进行安装&#xff08;方法二&#xff09; 先安装epel sudo yum install yum-utils 安装完成后&#xff0c;查看安装的epel包即可 sudo yum install epel 3 开始安装nginx 上面的两个方法不管选择哪个&…...