【selenium关键补充】——全栈开发——如桃花来

news/2024/10/29 0:30:26/

目录索引

  • ==selenium验证码处理:==
    • 截图:
      • *数字&文字&字母验证码--------根据图片输入:*
      • *滑块验证码--------以豆瓣为例(对接打码平台计算滑动距离):*
      • *图案点击验证码--------B站登录案例:*
      • *京东登录案例(参考:精确度低)--------滑动验证<计算型>:*
      • *图案点击&滑块双重验证--------12306登录案例:*
  • ==selenium控制标签页的切换:==
    • 代码演示:
  • ==selenium控制iframe的切换:==
    • 代码演示:
      • *对于ifame的语法补充:*
        • 1. 恢复默认页面方法
        • 2. 跳回最外层的页面
        • 3. 跳回上层的页面
        • 4. 切换到定位的frame标签嵌套的页面中
        • 5. 利用切换标签页的方式切出frame标签
  • ==利用selenium获取cookie的方法:==
    • 获取cookie:
    • 字典推导式转换:
    • 删除cookie:
      • *删除一条cookie:*
      • *删除所有的cookie:*
  • ==selenium使用代理IP:==
    • 代码演示:
  • ==selenium替换user-agent:==
    • 代码演示:
  • ==拓展知识点:==
    • selenium防检测:
      • *第一种:*
      • *第二种(直接添加上去即可):*
    • selenium禁止弹窗:
    • selenium清空输入:
    • selenium模拟回车:
    • selenium下拉框选择:
    • selenium鼠标悬停:

selenium验证码处理:

在selenium的控制下,我们手动输入验证码很可能被网站识别为爬虫,所以我们需要进行自动处理
验证码处理分为两种方式,一种是截图形式

截图:

数字&文字&字母验证码--------根据图片输入:

from selenium import webdriver
from PIL import Image
from requests_html import HTMLSessionsession = HTMLSession()
import base64
import time
driver = webdriver.Chrome()
# 窗口最大化
driver.maximize_window()
start_url = 'http://www.jianjiaoshuju.com/path/login.htm'
driver.get(start_url)#第一种:通过截图
driver.find_element_by_xpath('/html/body/div[2]/div/div[1]/ul/li[1]/input').send_keys('16607440667')
driver.find_element_by_xpath('/html/body/div[2]/div/div[1]/ul/li[2]/input').send_keys('songxu3523520')
#核心操作 (一):通过截图,获得验证码图片,直接复制照搬即可
'''
driver.save_screenshot('首页.png')
#获取验证码所在的标签
img = driver.find_element_by_xpath('/html/body/div[2]/div/div[1]/ul/li[3]/div/span/img')
#实例化标签对象
location = img.location
#获取标签大小
size = img.size
# 获取验证码上下左右的坐标
#该位置的坐标是根据电脑不同的分辨率计算的,后面+的数字可以直接删掉,如果二次截图截的不准确,就通过加值进行微调
left = location['x'] + 300
top = location['y'] + 110
right = left + size['width'] + 20
bot = top + size['height'] + 10
#打开首页.png图片,这里是二次截图
photo = Image.open('首页.png')
img_obj = photo.crop((left, top, right, bot))
img_obj.save('验证码.png')
#对接第三方平台,导入超级鹰等包
#操作省略"""
# AppCode:	20B9054575C6917DE9BC05175DDAD2D2
# AppKey:	AKIDa0fac224bccad10c4ea86d9b73bd4f62
# AppSecret:	a5a51b5a2cff7dcd5fdc9cd82d11e7bd
#
# 
'''
#核心操作(二):直接获取验证码图片
# 定位验证码所在的标签位置
img_obj = driver.find_element_by_xpath('/html/body/div[2]/div/div[1]/ul/li[3]/div/span/img')
# 截图 ---- 直接截图
img_obj.screenshot('验证码2.png')
"""验证码图片base64加密字符串"""
with open('验证码2.png', 'rb')as f:base64_data = base64.b64encode(f.read()).decode()
img_url = 'http://apigateway.jianjiaoshuju.com/api/v_1/yzm.html'
headers = {'AppCode': '20B9054575C6917DE9BC05175DDAD2D2','AppKey': 'AKIDa0fac224bccad10c4ea86d9b73bd4f62','AppSecret': 'a5a51b5a2cff7dcd5fdc9cd82d11e7bd'
}data = {'v_pic': base64_data,'v_type': 'ne4'
}response = session.post(img_url, data=data, headers=headers).json()
img_code = response['v_code']
driver.find_element_by_xpath('/html/body/div[2]/div/div[1]/ul/li[3]/div/div/input').send_keys(img_code)
driver.find_element_by_xpath('/html/body/div[2]/div/div[1]/ul/li[4]/button').click()
time.sleep(1)
driver.find_element_by_xpath('//*[@id="layui-layer2"]/div[3]/a').click()

滑块验证码--------以豆瓣为例(对接打码平台计算滑动距离):

from selenium import webdriver
from requests_html import HTMLSession
import base64
session = HTMLSession()
import time
driver = webdriver.Chrome()
driver.implicitly_wait(10)
# 窗口最大化
driver.maximize_window()
start_url = 'https://accounts.douban.com/passport/login_popup?login_source=anony'
driver.get(start_url)
# 点击密码登录
driver.find_element_by_xpath('/html/body/div[1]/div[1]/ul[1]/li[2]').click()
driver.find_element_by_id('username').send_keys('16607440667')
driver.find_element_by_id('password').send_keys('aef123456')
driver.find_element_by_xpath('/html/body/div[1]/div[2]/div[1]/div[5]/a').click()
"""在登录之后会弹出验证码"""
time.sleep(10)
el_iframe_1 = driver.find_element_by_id('tcaptcha_iframe')
driver.switch_to.frame(el_iframe_1)
# 定位滑动验证码标签位置
img_obj = driver.find_element_by_css_selector('#slideBg')
print(img_obj)
# 保存验证码
img_obj.screenshot('豆瓣.png')
"""核心部分"""
headers = {'AppCode': '20B9054575C6917DE9BC05175DDAD2D2','AppKey': 'AKIDa0fac224bccad10c4ea86d9b73bd4f62','AppSecret': 'a5a51b5a2cff7dcd5fdc9cd82d11e7bd'
}
with open('豆瓣.png', 'rb')as f:base64_data = base64.b64encode(f.read()).decode()
img_url = 'http://apigateway.jianjiaoshuju.com/api/v_1/yzmCrd.html'
data = {'v_pic': base64_data,'v_type': 'sld'
}
response = session.post(img_url, headers=headers, data=data).json()
print(response)

图案点击验证码--------B站登录案例:

# !/usr/bin/env python
# -*- coding: utf-8 -*-
# ------------------------------import time, base64, json, requests
from selenium import webdriver
from selenium.webdriver import ActionChains# def main():
# 1、实例化 driver对象
driver = webdriver.Chrome()
driver.maximize_window()
driver.get(r'https://passport.bilibili.com/login')
driver.implicitly_wait(10)# aef、定位 账号 和 密码标签
driver.find_element_by_id('login-username').send_keys(r'')
time.sleep(2)
driver.find_element_by_id('login-passwd').send_keys('')
time.sleep(2)
driver.find_element_by_css_selector('#geetest-wrap > div > div.btn-box > a.btn.btn-login').click()# 3、获取弹窗验证图片
time.sleep(2)
driver_img = driver.find_element_by_css_selector('body > div.geetest_panel.geetest_wind > div.geetest_panel_box.geetest_no_logo.geetest_panelshowclick > div.geetest_panel_next > div')
driver_img.screenshot('验证码.png')
time.sleep(3)# 4、对接打码平台
print(r'-----------------------------正在对接打码平台--------------------------------' + '\n')
with open('./验证码.png', 'rb') as f:base64_data = base64.b64encode(f.read())b64 = base64_data.decode()
data = {"username": '15675209157', "password": 'q6631801', "image": b64, 'typeid': 21}
result = json.loads(requests.post("http://api.ttshitu.com/imageXYPlus", json=data).text)
if result['success']:code_result = result["data"]["result"]
else:code_result = result["message"]
print(r'----------------识别成功:当前验证码识别结果为:{}---------'.format(code_result) + '\n')# 5、获取验证字 定位
print(r'-----------------------------正在点击验证码----------------------------------' + '\n')
for code in code_result.split(r'|'):x = int(code.split(',')[0])y = int(code.split(',')[1])# 6、设置验证码点击方式ActionChains(driver).move_to_element_with_offset(driver_img, x, y).click().perform()time.sleep(1)
print(r'--------------------------------验证码点击完成---------------------------------' + '\n')# 点击确定,登录账号
time.sleep(3)
driver.find_element_by_css_selector('body > div.geetest_panel.geetest_wind > div.geetest_panel_box.geetest_no_logo.geetest_panelshowclick > div.geetest_panel_next > div > div > div.geetest_panel > a > div').click()
print(r'---------------------------------账号登录成功----------------------------------')

京东登录案例(参考:精确度低)--------滑动验证<计算型>:

from 案例文件夹.selenium处理验证码 import pwd
from selenium.webdriver import ActionChains
from urllib import request
from selenium import webdriver
import numpy as np
import time, cv2"""创建driver对象"""
driver = webdriver.Chrome()
driver.maximize_window()"""准备起始的访问url地址"""
start_url = 'https://www.jd.com/'"""访问"""
driver.get(start_url)
time.sleep(2)"""跳转登录页面"""
driver.find_element_by_link_text('你好,请登录').click()
time.sleep(1.5)"""账号密码登录"""
driver.find_element_by_link_text('账户登录').click()"""账户密码输入"""
driver.find_element_by_id('loginname').send_keys('16607440667')
driver.find_element_by_id('nloginpwd').send_keys(pwd)"""登录按钮点击"""
driver.find_element_by_id('loginsubmit').click()"""获取验证码缺口图片url地址"""
# 背景缺口图链接
backimgUrl = driver.find_element_by_xpath(r'//div/div[@class="JDJRV-bigimg"]/img').get_attribute("src")
# 块状缺口链接
gapUrl = driver.find_element_by_xpath(r'//div/div[@class="JDJRV-smallimg"]/img').get_attribute("src")
request.urlretrieve(backimgUrl, "backing.png")
request.urlretrieve(gapUrl, "gap.png")"""将图片灰度化"""
# 获取图片并灰度化
block = cv2.imread("gap.png", 0)
template = cv2.imread("backing.png", 0)
# 二值化后的图片名称
blockName = "block.jpg"
templateName = "template.jpg"
# 将二值化后的图片进行保存
cv2.imwrite(blockName, block)
cv2.imwrite(templateName, template)
block = cv2.imread(blockName)
block = cv2.cvtColor(block, cv2.COLOR_RGB2GRAY)
block = abs(255 - block)
cv2.imwrite(blockName, block)
block = cv2.imread(blockName)
template = cv2.imread(templateName)
# 获取偏移量
result = cv2.matchTemplate(block, template,cv2.TM_CCOEFF_NORMED)  # 查找block在template中的位置,返回result是一个矩阵,是每个点的匹配结果
x, y = np.unravel_index(result.argmax(), result.shape)
print(x, y)"""计算滑动距离"""
print("需要移动的距离", y)
track = []  # 移动轨迹
current = 0  # 当前位移
# 减速阈值
mid = y * 4 / 5  # 前4/5段加速 后1/5段减速
t = 0.2  # 计算间隔
v = 0  # 初速度
while current < y:if current < mid:a = 3  # 加速度为+3else:a = -3  # 加速度为-3v0 = v  # 初速度v0v = v0 + a * t  # 当前速度move = v0 * t + 1 / 2 * a * t * t  # 移动距离current += move  # 当前位移track.append(round(move))  # 加入轨迹"""执行滑动"""
slider = driver.find_elements_by_xpath(r'//div[@class="JDJRV-slide-inner JDJRV-slide-btn"]')[0]
ActionChains(driver).click_and_hold(slider).perform()
for x in track:  # 只有水平方向有运动 按轨迹移动ActionChains(driver).move_by_offset(xoffset=x-20, yoffset=0).perform()
time.sleep(1)
ActionChains(driver).release().perform()  # 松开鼠标

图案点击&滑块双重验证--------12306登录案例:

from my_Spider import user_12306, pass_wd_12306
from selenium import webdriver
from selenium.webdriver import ActionChains
driver = webdriver.Chrome()
from requests_html import HTMLSession
session = HTMLSession()
import time, base64, randomstart_url = 'https://kyfw.12306.cn/otn/resources/login.html'
# 窗口最大化
driver.maximize_window()
driver.get(start_url)
# 点击账号登录
driver.find_element_by_xpath('/html/body/div[2]/div[2]/ul/li[2]/a').click()
driver.find_element_by_id('J-userName').send_keys(user_12306)
driver.find_element_by_id('J-password').send_keys(pass_wd_12306)
# 由于验证码只显示一半,需要执行窗口向下滑动
js = 'scrollTo(0, {})'.format(500)
driver.execute_script(js)
time.sleep(1)
# 定位验证码所在的标签
img_obj = driver.find_element_by_xpath('//*[@id="J-loginImg"]')
img_obj.screenshot('12306验证码.png')
# 读取验证码然后base64加密
with open('12306验证码.png', 'rb')as f:base64_data = base64.b64encode(f.read()).decode()img_url = 'http://apigateway.jianjiaoshuju.com/api/v_1/yzmCrd.html'
data = {'v_pic': base64_data,'v_type': 'crd'
}
headers = {'AppCode': '20B9054575C6917DE9BC05175DDAD2D2','AppKey': 'AKIDa0fac224bccad10c4ea86d9b73bd4f62','AppSecret': 'a5a51b5a2cff7dcd5fdc9cd82d11e7bd','user-agent': ua.chrome
}
response = session.post(img_url, headers=headers, data=data).json()
print(response)
"""对接打码平台"""
headers = {'AppCode': '20B9054575C6917DE9BC05175DDAD2D2','AppKey': 'AKIDa0fac224bccad10c4ea86d9b73bd4f62','AppSecret': 'a5a51b5a2cff7dcd5fdc9cd82d11e7bd','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36'
}
post_url = 'http://apigateway.jianjiaoshuju.com/api/v_1/yzmCrd.html'
with open('验证码12306.png', 'rb')as f:base64_data = base64.b64encode(f.read()).decode()
data = {'v_pic': base64_data,'v_type': 'crd'
}
response = session.post(post_url, headers=headers, data=data).json()
print(response)
v_code = response['v_code']
for code in v_code.split('|'):# 获取x坐标x = int(code.split(',')[0])# 获取y坐标y = int(code.split(',')[1])# 执行点击                                        验证码的对象,x,yActionChains(driver).move_to_element_with_offset(img, x, y).click().perform()# 每次停留0.5秒,模拟人的判断
"""点击登录"""
time.sleep(random.randint(1, 2))
driver.find_element_by_id('J-login').click()"""处理滑块验证码"""
# 定位滑块验证码的长度
div_size_obj = driver.find_element_by_xpath('//*[@id="nc_1__scale_text"]/span')
# 获取宽高
div_size = div_size_obj.size
# 定位滑块按钮位置
button = driver.find_element_by_xpath('//*[@id="nc_1_n1z"]')
# 实例化
button_location = button.location
# 鼠标拖动操作
# 计算出拖动距离
y = button_location['y']
print(y)  # 332
# 鼠标的拖动操作:
# ActionChains:可以控制鼠标,鼠标按钮操作,上下文切换等等
"""第一种模式"""
action = ActionChains(driver)
action.click_and_hold(button).perform()
action.move_by_offset(332, 0)
action.release().perform()
"""第二种模式"""
ActionChains(driver).click_and_hold(button).move_by_offset(y, 0).perform()

selenium控制标签页的切换:

窗口切换:
    -获取所有标签页的窗口句柄
    -利用窗口句柄字切换到句柄指向的标签页
    -窗口句柄:指的是指向标签页对象的标识

解析:

1.获取当前所有的标签页的句柄构成的列表

​current_windows = driver.window_handles

2.根据标签页句柄列表索引下标进行切换

driver.switch_to.window(current_windows[0])

代码演示:

from selenium import webdriver
import time
# 创建driver对象
driver = webdriver.Chrome()
# 访问的起始的url地址
start_url = 'https://www.baidu.com'
# 访问
driver.get(url=start_url)
time.sleep(1)
driver.find_element_by_id('kw').send_keys('python')
time.sleep(1)
driver.find_element_by_id('su').click()
time.sleep(1)# 通过执行js来新开一个标签页
js = 'window.open("https://www.csdn.net");'
driver.execute_script(js)
time.sleep(1)# 1.获取所有浏览器窗口
windows = driver.window_handles# 2.根据窗口索引进行切换
driver.switch_to.window(windows[0])
time.sleep(1)
driver.switch_to.window(windows[1])

selenium控制iframe的切换:

iframe是html中常用的一种技术,即一个页面中嵌套了另一个网页,selenium默认是访问不了frame中的内容的,对应的解决思路是driver.switch_to.frame(frame_element)

代码演示:

# 网易邮箱登录from selenium import webdriver
import timedef login(user, password):driver = webdriver.Chrome()driver.get("https://email2.163.com/")# browser.maximize_window()driver.switch_to.frame(driver.find_element_by_xpath('//iframe[starts-with(@id,"x-URS")]'))time.sleep(1)driver.find_element_by_xpath('//input[@name="email"]').send_keys(user)driver.find_element_by_xpath('//input[@name="password"]').send_keys(password)driver.find_element_by_xpath('//*[@id="dologin"]').click()time.sleep(2)print(driver.page_source)driver.save_screenshot("163.png")time.sleep(3)# driver.quit()if __name__ == '__main__':login('163邮箱帐号', '密码')

对于ifame的语法补充:

1. 恢复默认页面方法

在frame表单中操作其他页面,必须先回到默认页面,才能进一步操作

driver.switch_to.default_content() 

2. 跳回最外层的页面

切换到最外层(对于多层页面,可通过该方法直接切换到最外层

driver.switch_to.default_content()

3. 跳回上层的页面

进行向上的单层切换

driver.switch_to.parent_frame()

4. 切换到定位的frame标签嵌套的页面中

driver.switch_to.frame(通过find_element_by函数定位的frame、iframe标签对象)

5. 利用切换标签页的方式切出frame标签

windows = driver.window_handles
driver.switch_to.window(windows[0]

利用selenium获取cookie的方法:

获取cookie:

#返回列表,其中包含的是完整的cookie信息,需要转换为字典.
driver.get_cookies() 

字典推导式转换:

#返回的列表中有好几个字典,我们可能会需要遍历循环,并取出里面的name和value组成键值对。来构成cookie信息
cookies_dict = {cookie['name']: cookie['value'] for cookie in driver.get_cookies()}

删除cookie:

删除一条cookie:

driver.delete_cookie('cookie_name')

删除所有的cookie:

driver.delete_all_cookies()

selenium使用代理IP:

#实例化配置对象
options = webdriver.ChromeOptions()
#配置对象添加使用代理ip的命令
options.add_argument('--proxy-server=http://202.20.16.82:9527')
#实例化带有配置对象的driver对象
driver = webdriver.Chrome('./chromedriver', chrome_options=options)

代码演示:

from selenium import webdriver# 1.创建一个配置对象
options = webdriver.ChromeOptions()
# 2.使用代理
options.add_argument('--proxy-server=http://192.168.129.130')
# 3.创建driver对象
driver = webdriver.Chrome(options=options)
# 4.设置起始的url地址
start_url = 'https://www.baidu.com'
# 访问
driver.get(url=start_url)

selenium替换user-agent:

#替换user-agent的方法
#实例化配置对象
options = webdriver.ChromeOptions()
#配置对象添加替换UA的命令
options.add_argument('--user-agent=Mozilla/5.0 HAHA')
#实例化带有配置对象的driver对象
driver = webdriver.Chrome('./chromedriver', chrome_options=options)

代码演示:

from selenium import webdriver
from fake_useragent import UserAgent
ua = UserAgent()
# 1.创建一个配置对象
options = webdriver.ChromeOptions()
# 2.使用代理
options.add_argument('--user-agent={}'.format(ua.chrome))
# ua = 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Mobile Safari/537.36'
# options.add_argument('user-agent' + ua)
# 3.创建driver对象
driver = webdriver.Chrome(options=options)
# 4.设置起始的url地址
start_url = 'https://www.baidu.com'
# 访问
driver.get(url=start_url)
# 验证
js = 'return navigator.userAgent'
aa = driver.execute_script(js)
print(aa)

拓展知识点:

selenium防检测:

第一种:

from selenium import webdriver
from selenium.webdriver import ChromeOptionsoption = ChromeOptions()     #实例化一个ChromeOptions对象
option.add_experimental_option('excludeSwitches', ['enable-automation'])  #以键值对的形式加入参数bro = webdriver.Chrome(executable_path='./chromedriver.exe',options=option)  #在调用浏览器驱动时传入option参数就能实现

第二种(直接添加上去即可):

driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", { "source": """ Object.defineProperty(navigator, 'webdriver', { get: () => undefined }) """ })

selenium禁止弹窗:

from selenium import webdriver
from selenium.webdriver.chrome.options import Optionschrome_options = Options()# 禁止弹窗
prefs = {'profile.default_content_setting_values':{'notifications': 2}}
# 禁止弹窗加入
chrome_options.add_experimental_option('prefs', prefs)
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.get(url)
# 就可以访问无通知弹窗的浏览器了

selenium清空输入:

from selenium import webdriver
import timebrowser = webdriver.Chrome()
browser.maximize_window()  # 设置浏览器大小:全屏
browser.get('https://www.baidu.com')# 定位输入框
input_box = browser.find_element_by_id('kw')
try:# 输入内容:seleniuminput_box.send_keys('selenium')print('搜索关键词:selenium')
except Exception as e:print('fail')
# 输出内容:搜索关键词:selenium# 定位搜索按钮
button = browser.find_element_by_id('su')
try:# 点击搜索按钮button.click()print('成功搜索')
except Exception as e:print('fail搜索')
# 输出内容:成功搜索# clear():清空输入框
try:input_box.clear()print('成功清空输入框')
except Exception as e:print('fail清空输入框')
# 输出内容:成功清空输入框

selenium模拟回车:

from selenium import webdriver
import timebrowser = webdriver.Chrome()
browser.maximize_window()  # 设置浏览器大小:全屏
browser.get('https://www.baidu.com')# 定位输入框
input_box = browser.find_element_by_id('kw')
# 输入关键词:selenium
input_box.send_keys('selenium')
# 模拟回车操作
try:input_box.submit()print('成功回车')
except Exception as e:print('fail')
# 输出内容:成功回车

selenium下拉框选择:

# 导入需要的模块Select()类是用来管理下拉框的
from selenium import webdriver
from selenium.webdriver.support.select import Select
import time
# 创建浏览器对象
driver = webdriver.Chrome()
driver.maximize_window()
# 访问贴吧的高级搜素
driver.get('https://tieba.baidu.com/f/search/adv')# 定位到下拉框元素
el_select = driver.find_element_by_name('rn')
# 创建一个下拉框对象
xialakuang = Select(el_select)# 三种方法选择下拉框选项
# 第一、通过选项的索引来选定选项(索引从0开始算)
xialakuang.select_by_index(0)
time.sleep(1)
xialakuang.select_by_index(2)
time.sleep(1)
xialakuang.select_by_index(1)
time.sleep(1)# 第二种方法:通过option标签的属性值选择
xialakuang.select_by_value('20')
time.sleep(1)
xialakuang.select_by_value('10')
time.sleep(1)
xialakuang.select_by_value('30')
time.sleep(1)# 第三种:通过文本选择(下拉框的值)
xialakuang.select_by_visible_text('每页显示20条')
time.sleep(1)
xialakuang.select_by_visible_text('每页显示10条')
time.sleep(1)
xialakuang.select_by_visible_text('每页显示30条')
time.sleep(1)# 打印选择的文本
# 查看第一个已选(若有多个已选则打印第一个,只有一个已选则打印一个)
print(xialakuang.first_selected_option.text)
# 打印所有已选的选项的文本
yixuan = xialakuang.all_selected_options
for i in yixuan:print('已选',i.text)
# 打印是否是多选
print(xialakuang.is_multiple)
# 打印所有选项(包括已选和未选的)
m_list = xialakuang.options
for a in m_list:print('选项',a.text)# # 关闭浏览器
# driver.quit()

selenium鼠标悬停:

from selenium.webdriver.common.action_chains import ActionChains
# 定位到需要悬停的标签
move = driver.find_element_by_id("xpath语法")
# 开始悬停
ActionChains(self.driver).move_to_element(move).perform()

http://www.ppmy.cn/news/97741.html

相关文章

GO开篇:手握Java走进Golang的世界

文章目录 一、Golang简介1、Go的诞生2、Go的官网域名3、Go的发展4、Go的设计思想5、Go的特点6、Go的性能7、Go的吉祥物 二、Go和Java的宏观对比1、编译型语言 or 解释型语言2、微观对比 三、Go应用场景1、开源上的应用 四、总结和后续 一、Golang简介 Go&#xff08;又称 Gola…

基于pytorch+transformers的车牌识别

目录 程序流程设计熟悉训练数据集CCPD2019数据集CCPD数据集标注信息单例再现 加载本地车牌数据集 程序流程设计 1&#xff0c;熟悉训练数据集&#xff1b; 2&#xff0c;加载本地车牌数据集&#xff1b; 3&#xff0c;定义网络模型&#xff1b; 4&#xff0c;输入数据集训练模…

RHCE8练习题

在系统上执行以下任务。 目录 1、安装和配置 Ansible 2、创建和运行 Ansible 临时命令 3、安装软件包

MATLAB入门教程005||MATLAB运算符||MATLAB算术运算

MATLAB运算符 MATLAB运算符 数组中唯一的值运算符是一个符号&#xff0c;它将要执行的数学或者逻辑操作传达给编译器执行。 MATLAB 设计工作主要是对整个矩阵和阵列。因此&#xff0c;运算符在 MATLAB 工作标和非标量数据。 MATLAB 的基本运算类型&#xff1a; 算术运算符…

HDFS学习笔记

HDFS1.0 1 什么是HDFS&#xff1f; HDFS的全称是&#xff1a;Hadoop DistributeFiles System&#xff0c;分布式文件系统。 在整个Hadoop技术体系中&#xff0c;HDFS提供了数据分布式存储的底层技术支持。 HDFS 由三个组件构成&#xff1a;NameNode&#xff08;NN&#xff…

23种设计模式中之中介者模式(Mediator Pattern)

前言&#xff1a;大家好&#xff0c;我是小威&#xff0c;24届毕业生&#xff0c;在一家满意的公司实习。本篇文章将23种设计模式中的迭代器模式&#xff0c;此篇文章为一天学习一个设计模式系列文章&#xff0c;后面会分享其他模式知识。 如果文章有什么需要改进的地方还请大佬…

若依源码解析:图片验证码生成

文章目录 摘要生成图片验证码的过程若依中的验证码生成控制器:CaptchaController验证码文本生成器:KaptchaTextCreator 摘要 若依通过合理的验证码生成流程和相应的代码实现&#xff0c;为应用程序提供了生成图片验证码和基于数学运算的验证码文本的功能&#xff0c;以增加系统…

【前端】关于如何将html、js、css等一个html网页打包成单一的exe可执行程序文件

要将 HTML、JS、CSS 等一个 HTML 网页打包成单一的可执行程序文件&#xff08;exe&#xff09;&#xff0c;通常需要使用一些工具和框架来实现的。 这里以Electron为例&#xff0c;详细说一下具体的打包过程 1.安装依赖&#xff1a; 确保已经安装了 Node.js。在命令行中进入你…