selenium基础教程(网页自动化 )

目录

一、配置环境

1.安装Selenium

2.安装谷歌浏览器驱动

二、selenium基础知识

1.对页面进行操作

(1)初始化浏览器对象

(2)访问页面用get()获取

(3)设置浏览器大小

(4)前进/后退页面。

(5)获取页面的基础属性

2.定位页面元素

(1)定位元素

(2)常用定位(by参数)

(3)百度搜索页面

3.模拟鼠标操作

(1)常见操作介绍

(2)悬停操作

(3)拖拽操作

(4)键盘组合操作

(5)模拟登录时的复杂操作

4.模拟键盘操作

(1)导入keys类并介绍

(2)百度搜索+回车

(3)常用组合键

(4)填写表单

5.延迟等待

(1)强制等待

(2)隐式等待(一般推荐)

(3)显式等待

(4)按回车关闭浏览器

6.切换操作

(1)窗口切换

A.两个窗口之间切换

B.多个窗口之间切换

(2)表单切换

A.通过IDid或name属性切换(最常用)

B.通过WebElement对象切换(最灵活)

C.处理嵌套iframe

D.关键方法总结

E.最佳实践和注意事项

7.对Cookie操作

8.下拉进度条做法

(1)找到页面高度

(2)缓慢分段滚动到页面底部(模拟阅读行为)

(3)滚到页面顶部

(4)滚到页面特定位置(三分之一)

(5)滚动到特定元素

(6)滑动到动态元素页面可见

(7)判断元素是否存在

9.xpath方法

(1)XPath路径表达式

(2)XPath语法通配符

(3)谓语

(4)基本Xpath定位

A.通过标签名定位

B.通过ID定位

C.通过 class 定位

(5)使用文本内容定位

A.精确文本匹配

B.部分文本匹配

(6)使用属性定位

A.属性组合

B.属性值部分匹配

(7)层级关系定位

A.父子关系

B.兄弟关系

C.父元素

(8)索引元素

(9)模糊定位

A.使用contains() 包含函数,文本包含某个词语

B.使用starts-with() 包含函数

C.使用count() 包含函数

D.使用last() 包含函数

E.使用position() 包含函数

(10)逻辑定位

(11)轴定位


简介:Selenium 是一套开源的自动化测试框架,主要用于 Web 应用程序的自动化测试。它支持多种编程语言(如 Python、Java、C#、JavaScript 等)和浏览器(Chrome、Firefox、Edge 等),可模拟用户操作(点击、输入、导航等),是 Web 自动化测试和爬虫开发的常用工具。

核心用途

  1. Web 自动化测试

    • 功能测试:模拟用户操作(登录、表单提交、页面跳转)。

    • 回归测试:确保代码更新后原有功能正常。

  2. 网页数据抓取

    • 处理动态加载内容(如 JavaScript 渲染的页面),比传统爬虫更强大。

  3. 自动化任务

    • 自动填写表单、批量操作网页、监控网站变化等。

一、配置环境

1.安装Selenium

pip install selenium

2.安装谷歌浏览器驱动

点击chrome浏览器最右侧的“三个点”图标,然后点击弹出的“帮助”中的“关于Google Chrome”,查看自己的版本信息。

找到自己版本的驱动,这样在下载对应版本的 Chrome 驱动即可(阿里云盘存有139.0版本的驱动)

打开 下载chromedriver.storage.googleapis.com/index.html。单击对应的版本。(这是国内的,没有最新的版本驱动)

Chrome for Testing availability这是下载最新驱动的网址(记得是下载下面的)

将 chromedriver.exe(或者驱动目录) 保存到任意位置,并把当前路径保存到环境变量

(环境变量--系统变量--path--新建--然后再把chromedriver.exe的路径放进去,在这里我的是C:\Program Files\Google\Chrome\Application\chrome-headless-shell-win64)。

(建议驱动目录保存在谷歌浏览器安装目录下)

为了防止谷歌一直更新,导致驱动与谷歌版本号不匹配。现在我们将谷歌禁止自动更新,在电脑中搜索服务,在里面找到Google更新的字眼,然后右击属性,将他禁止。

添加驱动成功后使用下面代码进行测试。(能弹出谷歌就说明驱动安装成功了)

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

弹出谷歌之后就会闪退,我们需要用到延迟等待,下面我们用谷歌搜索一下百度试试(弹出百度界面说明可以正常使用了)

from selenium import webdriver
import time
# 初始化浏览器为chrome浏览器
browser = webdriver.Chrome()

browser.get(r'https://www.baidu.com/')

time.sleep(5)

二、selenium基础知识

1.对页面进行操作

(1)初始化浏览器对象

前面我们已经把Chrome驱动添加到环境变量了,所以我们可以直接初始化界面。

from selenium import webdriver

# 初始化浏览器为chrome浏览器
browser = webdriver.Chrome()

# 关闭浏览器
browser.close()

(2)访问页面用get()获取

也可以将网址保存在path中,这样后期更改网址方便。

这里网址中前面有个r:r表示"raw string"(原始字符串),它的作用是让字符串中的反斜杠 \ 不被解释为转义字符。

在这个特定的网址情况下,其实不需要使用r。

r主要用在文件路径正则表达式中,因为这些地方经常包含反斜杠\

path=r'https://www.baidu.com/'
from selenium import webdriver
# 初始化浏览器为chrome浏览器
browser = webdriver.Chrome()

# 访问百度
path='https://www.baidu.com/'
browser.get(path)

# 关闭浏览器
browser.close()

(3)设置浏览器大小

set_window_size(宽度,高度)方法可以用来设置浏览器大小(就是分辨率),而maximize_window则是设置浏览器为全屏。

from selenium import webdriver
import time  

browser = webdriver.Chrome()

# 设置浏览器大小:全屏
browser.maximize_window()   
browser.get('https://www.baidu.com')  
time.sleep(2)

# 设置分辨率 500宽度*500高度
browser.set_window_size(500,500)  
time.sleep(2)

# 关闭浏览器
browser.close()

(4)前进/后退页面。

forward()方法可以用来实现前进,back()可以用来实现后退。同理可得,在点击跳转页面之后,也可以用这个来实现前进和回退。

from selenium import webdriver
import time  

browser = webdriver.Chrome()

# 设置浏览器全屏
browser.maximize_window()   

#打开百度
browser.get('https://www.baidu.com')  
#请求间隔两秒
time.sleep(2)

# 打开b站
browser.get('https://www.bilibili.com/')  
time.sleep(2)

# 后退到百度
browser.back()  
time.sleep(2)

# 前进到b站
browser.forward() 
time.sleep(2)

# 关闭浏览器
browser.close()

(5)获取页面的基础属性

如网页标题、网址、浏览器名称、页面源码等信息。

from selenium import webdriver

browser = webdriver.Chrome()
browser.get('https://www.baidu.com') 

# 网页标题
print(browser.title)

# 当前网址
print(browser.current_url)

# 浏览器名称
print(browser.name)

# 网页源码
print(browser.page_source)

2.定位页面元素

按 【F12】 进入开发者工具。我们要做的就是从代码中定位获取我们需要的元素。进入之后,要是复制了Xpath,可以按【ctrl+f】组合键来搜索元素。

(1)定位元素

下面我们来介绍一些Selenium提供的一些方法。通过webdriver对象的 find_element(by=“属性名”, value=“属性值”)(通常用ID,会更准确)

属性函数
xpathfind_element(by=By.XPATH, value="")
link_textfind_element(by=By.LINK_TEXT, value="")
partial_link_textfind_element(by=By.PARTIAL_LINK_TEXT, value="")
tag_namefind_element(by=By.TAG_NAME, value="")
css_selectorfind_element(by=By.CSS_SELECTOR, value="")
idfind_element(by=By.ID, value="")
class_nameind_element(by=By.CLASS_NAME, value="")

(2)常用定位(by参数)

from selenium.webdriver.common.by import By

# 定位ID为"username"的元素
username_input = driver.find_element(by=By.ID, value="username")

# 定位name为"email"的元素
email_input = driver.find_element(by=By.NAME, value="email"

# 定位class为"btn-primary"的元素
submit_btn = driver.find_element(by=By.CLASS_NAME, value="btn-primary")

# 定位第一个<div>元素
div_element = driver.find_element(by=By.TAG_NAME, value="div")

# 定位文本为"登录"的链接
login_link = driver.find_element(by=By.LINK_TEXT, value="登录")

# 定位包含"忘记密码"的链接
forgot_pw_link = driver.find_element(by=By.PARTIAL_LINK_TEXT, value="忘记密码")

#多种CSS选择器示例
element1 = driver.find_element(by=By.CSS_SELECTOR, value="input[type='text']")
element2 = driver.find_element(by=By.CSS_SELECTOR, value=".container > .header")
element3 = driver.find_element(by=By.CSS_SELECTOR, value="#submit-btn")

# 多种XPath示例
element1 = driver.find_element(by=By.XPATH, value="//input[@name='username']")
element2 = driver.find_element(by=By.XPATH, value="//div[@class='content']/p[1]")
element3 = driver.find_element(by=By.XPATH, value="//button[contains(text(),'提交')]")

(3)百度搜索页面

进入百度,找到搜索框进行定位,找到元素,下面用的是ID,还可以使用CSS或者Xpath来定位。

(请求的时候要延迟等待time.sleep(4)或者隐式等待,不然页面可能会闪退)

登录界面会涉及到需要验证码识别登录(再继续学习Python OCR工具pytesseract详解)

网址:https://blog.youkuaiyun.com/u010698107/article/details/121736386

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")

# 定位搜索框并输入文本
search_box = driver.find_element(by=By.ID, value="chat-textarea")
search_box.send_keys("Selenium自动化测试")

# 定位搜索按钮并点击
search_btn = driver.find_element(by=By.ID, value="chat-submit-button")
search_btn.click()

time.sleep(4)
search_box = driver.find_element(by=By.XPATH, value='//*[@id="chat-textarea"]')

3.模拟鼠标操作

导入ActionChains 类。

from selenium.webdriver.common.action_chains import ActionChains

(1)常见操作介绍

操作函数
右击context_click()
双击double_click()
拖拽double_and_drop()
悬停move_to_element()
执行perform()

(2)悬停操作

先找到元素定位,再用鼠标进行悬停。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time
from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Chrome()

#设置全屏
driver.maximize_window()

# 创建ActionChains实例
actions = ActionChains(driver)  
driver.get("https://www.baidu.com")

# 用ID定位到设置链接
settings = driver.find_element(By.ID, value="s-usersetting-top")

# 鼠标悬停操作
actions.move_to_element(settings).perform()
time.sleep(10)
print("鼠标已悬停在设置上")

(3)拖拽操作

这里只是举例说明,没有在网页上操作过。

# 拖拽元素从source到target
source = driver.find_element(By.ID, "draggable")
target = driver.find_element(By.ID, "droppable")

actions.drag_and_drop(source, target).perform()
# 或者使用:
# actions.click_and_hold(source).move_to_element(target).release().perform()
print("拖拽完成")

(4)键盘组合操作

from selenium.webdriver.common.keys import Keys

search_box = driver.find_element(By.ID, "kw")
search_box.send_keys("selenium")

# Ctrl+A (全选)
actions.key_down(Keys.CONTROL).send_keys("a").key_up(Keys.CONTROL).perform()

# Ctrl+C (复制)
actions.key_down(Keys.CONTROL).send_keys("c").key_up(Keys.CONTROL).perform()

# 在新输入框粘贴
another_input = driver.find_element(By.ID, "another-input")
another_input.click()
actions.key_down(Keys.CONTROL).send_keys("v").key_up(Keys.CONTROL).perform()

(5)模拟登录时的复杂操作

def complex_login_flow():
    driver.get("http://example.com/login")
    
    # 1. 输入用户名
    username = driver.find_element(By.NAME, "username")
    actions.click(username).send_keys("testuser").perform()
    
    # 2. Tab键切换到密码框
    actions.send_keys(Keys.TAB).perform()
    
    # 3. 输入密码
    actions.send_keys("password123").perform()
    
    # 4. 回车登录
    actions.send_keys(Keys.ENTER).perform()
    
    print("登录流程完成")

4.模拟键盘操作

(1)导入keys类并介绍

from selenium.webdriver.common.keys import Keys
操作函数
删除键send_keys(Keys.BACK_SPACE)
空格键 send_keys(Keys.SPACE)
制表键  send_keys(Keys.TAB)
回退键 send_keys(Keys.ESCAPE)
回车send_keys(Keys.ENTER)
全选send_keys(Keys.CONTRL,‘a’)
复制end_keys(Keys.CONTRL,‘c’)
剪切 send_keys(Keys.CONTRL,‘x’)
粘贴send_keys(Keys.CONTRL,‘v’)
键盘F1send_keys(Keys.F1)

(2)百度搜索+回车

import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
 
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.maximize_window()
time.sleep(5)

# 定位百度输入框,并输入内容
driver.find_element("id","chat-textarea").send_keys("Selenium自动化测试")

# 定位百度输入框,按下回车键,以此代替点击搜索按钮
driver.find_element("id","chat-textarea").send_keys(Keys.ENTER)

time.sleep(5)
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time
 
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.maximize_window()
time.sleep(5)

#先定位到搜索框
search_box = driver.find_element(by=By.ID, value="chat-textarea")

#直接输入并回车
search_box.send_keys("Selenium自动化测试"+ Keys.ENTER)

time.sleep(5)
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time
 
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.maximize_window()
time.sleep(5)

#先定位到搜索框
search_box = driver.find_element(by=By.ID, value="chat-textarea")

#输入内容
search_box.send_keys("Selenium自动化")

#输入回车
search_box.send_keys(Keys.RETURN)  # ENTER和RETURN效果相同

time.sleep(5)

(3)常用组合键

我们经常使用的Ctrl+A,Ctrl+C都是组合键。在使用按键操作的时候我们需要借助一下send_keys()来模拟操作。

Keys.CONTROL也就是我们键盘上的Ctrl键。

import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
 
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.maximize_window()
time.sleep(5)
 
driver.find_element("id", "chat-textarea").send_keys("Selenium自动化测试")
#全选
driver.find_element("id", "chat-textarea").send_keys(Keys.CONTROL, 'a')
#复制
driver.find_element("id", "chat-textarea").send_keys(Keys.CONTROL, 'c')
#粘贴
driver.find_element("id", "chat-textarea").send_keys(Keys.CONTROL, 'v')
#粘贴
driver.find_element("id", "chat-textarea").send_keys(Keys.CONTROL, 'v')

time.sleep(5)

(4)填写表单

#改成要填写表单的地址
driver.get("http://example.com/form")
    
#定位到元素
name_field = driver.find_element(By.NAME, "name")

# 填写表单并使用Tab键切换
name_field.send_keys("张三" + Keys.TAB + "25" + Keys.TAB + "zhangsan@email.com")

5.延迟等待

需要等待一定的时间,整个页面才会完整的加载出来,所以我们用get()获取页面之后,需要延迟等待几秒,下面来介绍一下延迟等待的三种方式。(一般我都是用强制等待)

(1)强制等待

在执行get方法之后,执行time.sleep(n)   强制等待n秒。使用简单,但效率低下,正式文本中尽量避免使用。

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")

# 强制等待5秒
time.sleep(5)

(2)隐式等待(一般推荐)

implicitly_wait()设置等待时间,如果到时间有元素节点没有加载出来,就会抛出异常。

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")

#隐式等待
driver.implicitly_wait(10)

(3)显式等待

设置一个等待时间和一个条件,在规定时间内,每隔一段时间查看下条件是否成立,如果成立那么程序就继续执行,否则就抛出一个超时异常。

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")

# 创建WebDriverWait实例,设置最大等待时间10秒,轮询间隔0.5秒
wait = WebDriverWait(driver, timeout=10, poll_frequency=0.5)

# 等待元素可见
search_box = wait.until(EC.visibility_of_element_located((By.ID, "chat-textarea")))

# 等待元素可点击
search_btn = wait.until(EC.element_to_be_clickable((By.ID, "chat-submit-button")))

# 输入搜索词
search_box.send_keys("Selenium")
search_btn.click()

(4)按回车关闭浏览器

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium import webdriver
import time

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")

# 创建WebDriverWait实例,设置最大等待时间50秒,轮询间隔0.5秒
wait = WebDriverWait(driver, timeout=50, poll_frequency=0.5)

# 等待元素可见
search_box = wait.until(EC.visibility_of_element_located((By.ID, "chat-textarea")))

# 等待元素可点击
search_btn = wait.until(EC.element_to_be_clickable((By.ID, "chat-submit-button")))

# 输入搜索词
search_box.send_keys("Selenium")
search_btn.click()


input("按回车键关闭浏览器")  # 等待用户输入
driver.quit()

6.切换操作

(1)窗口切换

switch_to.windows() 

在 selenium 操作页面的时候,可能会因为点击某个链接而跳转到一个新的页面(打开了一个新标签页),这时候 selenium 实际还是处于上一个页面的,需要我们进行切换才能够定位最新页面上的元素。

窗口切换需要使用 switch_to.windows() 方法。

在点击跳转后,使用 switch_to 切换窗口,window_handles 返回的 handle 列表是按照页面出现时间进行排序的,最新打开的页面肯定是最后一个,这样用 driver.window_handles[-1] + switch_to 即可跳转到最新打开的页面了。

那如果打开的窗口有多个,如何跳转到之前打开的窗口,如果确实有这个需求,那么打开窗口是就需要记录每一个窗口的 key(别名) 与 value(handle),保存到字典中,后续根据 key 来取 handle 。

A.两个窗口之间切换
driver.switch_to.window(driver.window_handles[-1])
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains

#搜索Selenium自动化测试得到网页1,再点击搜索出来的第一个网页得到网页2,在网页2再点击一个地方得到网页3,最后把网页2关掉。

#1、先进入到百度,并设置为全屏,设置全局等待缓冲6秒
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://www.baidu.com")
driver.implicitly_wait(6)

#2、先定位到搜索框,输入Selenium自动化测试并按回车
search_box = driver.find_element(by=By.ID, value="chat-textarea")
search_box.send_keys("Selenium自动化测试"+ Keys.ENTER)
#time.sleep(3)

#3、先获取并保存当前(主窗口)的句柄
main_window_handle = driver.current_window_handle

#4、找到要点击的元素定位,并创建ActionChains实例,再点击一个网页
search_box2 = driver.find_element(by=By.XPATH, value='//*[@id="1"]/div/h3/a')
actions = ActionChains(driver) 
actions.click (search_box2).perform()

#5、等待新窗口打开,并获取所有窗口句柄(有时候句柄可能不止两个)
all_handles = driver.window_handles

#6. 找到新窗口的句柄
# 方法A: 循环遍历,找到不是主窗口句柄的那个(当有多个窗口时)
#for handle in all_handles:
#    if handle != main_window_handle:
#        new_window_handle = handle
#        break

# 方法B(更简单): 直接假设新窗口是列表最后一个
new_window_handle = all_handles[-1]

#7. 切换到新窗口
driver.switch_to.window(new_window_handle)
print(f"已切换到新窗口,标题是: {driver.title}")

#8. 切换之后现在可以在新窗口中进行操作了,找到元素并点击
element_in_new_tab = driver.find_element(By.XPATH, '//*[@id="root"]/div/div[1]/div[5]/div[1]/div/div/div/a')
element_in_new_tab.click()

#8. 操作完成后,如果需要关闭新窗口并回到主窗口
driver.close()  # 关闭当前(新)标签页
driver.switch_to.window(main_window_handle) # 将控制权交回主窗口
print(f"已切换回主窗口,标题是: {driver.title}")

input("按回车键关闭浏览器")  # 等待用户输入
driver.quit()
B.多个窗口之间切换
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains

#先进入到百度,并设置为全屏,设置全局等待缓冲6秒
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://www.baidu.com")
driver.implicitly_wait(6)

#输入Selenium自动化测试并按回车
search_box = driver.find_element(by=By.ID, value="chat-textarea")
search_box.send_keys("Selenium自动化测试"+ Keys.ENTER)

#获取并保存当前(主窗口)的句柄
main_window_handle = driver.current_window_handle

#点击网页
for i in range(2):
    driver.find_element(by=By.XPATH, value='//*[@id="1"]/div/h3/a').click()

#获取所有窗口句柄
all_handles = driver.window_handles

# 切换到第二个新窗口(索引为2,因为0是主窗口)
driver.switch_to.window(all_handles[2])
driver.find_element(By.XPATH, '//*[@id="root"]/div/div[1]/div[5]/div[1]/div/div/div/a').click()

# 切换到第一个新窗口(索引为1)
driver.switch_to.window(all_handles[1])
driver.find_element(By.XPATH, '//*[@id="root"]/div/div[1]/div[5]/div[1]/div/div/div/a').click()

# 最后切换回主窗口
driver.switch_to.window(main_window_handle)


print(f"已切换回主窗口,标题是: {driver.title}")
input("按回车键关闭浏览器")  # 等待用户输入
driver.quit()

(2)表单切换

很多页面也会用带 frame/iframe 表单嵌套,对于这种内嵌的页面 selenium 是无法直接定位的,需要使用 switch_to.frame() 方法将当前操作的对象切换成 frame/iframe 内嵌的页面。比如第三方登录窗口(微信、QQ登录)

switch_to.frame() 默认可以用的 id 或 name 属性直接定位,但如果 iframe 没有 id 或 name ,这时就需要使用 xpath 进行定位。

假如我们有以下HTML结构:

<html>
<body>
    <h1>主页面标题</h1>
    
    <!-- 第一个iframe,有id -->
    <iframe id="loginFrame" name="login" src="login.html">
        #document
        <html>
            <body>
                <input type="text" id="username" placeholder="用户名">
                <input type="password" id="password" placeholder="密码">
                <button id="loginBtn">登录</button>
            </body>
        </html>
    </iframe>

    <!-- 第二个iframe,只有class -->
    <iframe class="video-player" src="video.html">
        #document
        <html>
            <body>
                <button id="playBtn">播放</button>
                <div id="videoContent">视频内容</div>
            </body>
        </html>
    </iframe>
</body>
</html>
A.通过IDid或name属性切换(最常用)
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome()
driver.get("your_page_url")

# 通过id切换
driver.switch_to.frame("loginFrame")  # 使用id

# 或者通过name切换(如果iframe有name属性)
# driver.switch_to.frame("login")  # 使用name

# 操作iframe内的元素
username_field = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.ID, "username"))
)
username_field.send_keys("testuser")

# 切换回主文档
driver.switch_to.default_content()

# 现在可以操作其他iframe或主文档元素
B.通过WebElement对象切换(最灵活)
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("your_page_url")

# 先定位到iframe元素本身
iframe_element = driver.find_element(By.CLASS_NAME, "video-player")

# 然后将该WebElement作为参数传入
driver.switch_to.frame(iframe_element)

# 操作第二个iframe中的视频控件
driver.find_element(By.ID, "playBtn").click()

# 切换回主文档
driver.switch_to.default_content()

假如我们有以下HTML结构:

<iframe id="outerFrame">
    #document
    <html>
        <body>
            <iframe id="innerFrame">
                #document
                <html>
                    <body>
                        <button id="deepButton">深层按钮</button>
                    </body>
                </html>
            </iframe>
        </body>
    </html>
</iframe>
C.处理嵌套iframe

有时候iframe内部还嵌套着其他iframe,需要层层切换。

# 切换到外层iframe
driver.switch_to.frame("outerFrame")

# 再切换到内层iframe
driver.switch_to.frame("innerFrame")

# 现在可以操作最内层的元素
driver.find_element(By.ID, "deepButton").click()

# 如果要返回主文档,需要逐层返回或直接跳回
driver.switch_to.parent_frame()  # 回到外层iframe
driver.switch_to.parent_frame()  # 回到主文档

# 或者直接跳回主文档
driver.switch_to.default_content()  # 直接回到最外层
D.关键方法总结
方法描述
switch_to.frame(frame_reference)切换到指定的iframe
switch_to.default_content()从任何iframe层级直接切换回最外层的主文档
switch_to.parent_frame()从当前iframe切换回它的父级(上一层)

E.最佳实践和注意事项

   a.优先使用id/name:通过id或name属性切换是最稳定可靠的方式。

   b.使用显式等待:在切换iframe后,使用WebDriverWait等待iframe内的元素加载完成。

   c.及时切换回主文档:操作完iframe后,记得使用 default_content() 或 parent_frame() 返回,否则后续查找元素会失败。

   d.处理不可见的iframe:有些iframe可能默认不显示,需要先触发某些操作才会出现

   e.调试技巧:如果找不到元素,首先检查:

  • 是否忘记了切换到正确的iframe?

  • 是否需要等待iframe加载?

  • iframe是否是动态加载的?

7.对Cookie操作

cookies 是识别用户登录与否的关键,爬虫中常常使用 selenium + requests 实现 cookie持久化,即先用 selenium 模拟登陆获取 cookie ,再通过 requests 携带 cookie 进行请求。

webdriver 提供 cookies 的三种操作:读取、添加、删除

get_cookies以字典的形式返回当前会话中可见的 cookie 信息
get_cookie(name)返回 cookie 字典中
key == namecookie 信息
add_cookie(cookie_dict)将 cookie 添加到当前会话中
delete_cookie(name)删除指定名称的单个 cookie
delete_all_cookies()删除会话范围内的所有cookie
from selenium import webdriver
browser = webdriver.Chrome()
# 知乎发现页
browser.get('https://www.zhihu.com/explore')

# 获取cookie
print(f'Cookies的值:{browser.get_cookies()}')

# 添加cookie
browser.add_cookie({'name':'才哥', 'value':'帅哥'})
print(f'添加后Cookies的值:{browser.get_cookies()}')

# 删除cookie
browser.delete_all_cookies()
print(f'删除后Cookies的值:{browser.get_cookies()}')

8.下拉进度条做法

execute_script方法

滚动方式JavaScript 代码示例适用场景
针对整个文档document.documentElement.scrollTop = 1000绝大多数标准网页5
针对 body 元素document.body.scrollTop = 1000一些旧式或特殊结构的网页
针对特定元素document.getElementById('myDiv').scrollTop = 1000页面内具有独立滚动区域的容器(如聊天框)
滚动到元素可见arguments[0].scrollIntoView();需要将特定元素滚动到视口内时
滚动指定距离window.scrollBy(0, 500);需要相对当前滚动位置进行滚动

注意:对于整个文档的滚动,document.documentElement.scrollTop 和 document.body.scrollTop 在不同浏览器或不同DOCTYPE声明的页面中行为可能不同。如果一个不行,可以尝试另一个。

其他滚动技巧

除了设置固定的 scrollTop,你还可以使用:

  • window.scrollTo(x, y): 滚动到文档中的特定坐标。(比如页面底部)

  • window.scrollBy(x, y): 相对于当前位置滚动一段距离。这在模拟逐段滚动阅读时很实用。

  • element.scrollIntoView(): 让特定的元素滚动到视口内。这是确保元素可见再进行操作(如点击)的推荐方法。

(1)找到页面高度

属性描述
window.innerHeight浏览器中间可视区域的高度
window.outerHeight整个浏览器窗口的高度
document.documentElement.clientHeight视口高度(不包括滚动条)
document.documentElement.scrollHeight整个网页的完整高度(包括需要滚动才能看到的部分)
document.documentElement.offsetHeight文档高度(包括边框和滚动条)
#获取页面高度,使用 || 操作符是因为不同浏览器对页面高度的计算方式不同
total_height = driver.execute_script("return document.body.scrollHeight || document.documentElement.scrollHeight;")
# 获取可视页面的高度
viewport_height = driver.execute_script("return window.innerHeight;") 

(2)缓慢分段滚动到页面底部(模拟阅读行为)

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time

# 初始化浏览器驱动 
driver = webdriver.Chrome() 
driver.get("https://baike.baidu.com/item/Selenium/18266")

#获取全页面高度(包括没有滑动到的部分),兼容不同浏览器
total_height = driver.execute_script("return document.body.scrollHeight || document.documentElement.scrollHeight;") 

#获取可视页面高度,并每次滚动一个视口高度的80%
viewport_height = driver.execute_script("return window.innerHeight;")
scroll_step = viewport_height * 0.8

#设置页面初始高度为0
current_position = 0  

#循环语句,当初始高度小于全页面高度时
while current_position < total_height:

# scrollTo(x,y)滑动到指定坐标的位置
    driver.execute_script(f"window.scrollTo(0, {current_position});")

#没滑动一次current_position就加上页面的百分80%高度
    current_position += scroll_step

# 暂停一下,模拟阅读速度
    time.sleep(0.5) 
 
# 最终确保滚动到底部
driver.execute_script("window.scrollTo(0, document.body.scrollHeight || document.documentElement.scrollHeight);")
print("已滚动到页面底部")

# 等待2秒观察效果
time.sleep(2)  

(3)滚到页面顶部

driver.execute_script("window.scrollTo(0, 0);")

(4)滚到页面特定位置(三分之一)

target_position = total_height // 3
driver.execute_script(f"window.scrollTo(0, {target_position});")

(5)滚动到特定元素

#异常处理框架
try:
    # 尝试精确查找和滚动
    ...
except Exception as e:
    # 降级处理方案
    ...
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time

# 初始化浏览器驱动 (请确保 chromedriver 在 PATH 环境变量中,或使用 executable_path 参数指定路径)
driver = webdriver.Chrome() 
driver.get("https://baike.baidu.com/item/Selenium/18266")
driver.implicitly_wait(30)
total_height = driver.execute_script("return document.body.scrollHeight || document.documentElement.scrollHeight;")

print("尝试滚动到‘发展历程’章节...")
try:
    # 使用更稳定的XPath尝试定位“发展历程”这个标题
    development_title = WebDriverWait(driver, 5).until(
            EC.presence_of_element_located((By.XPATH, "//h2[contains(., '发展历程')] | //h2[contains(., '历史')] | //div[contains(@class, 'heading') and contains(., '发展历程')]"))
            # 如果找不到“发展历程”,尝试找“历史”或其他标题,或者根据实际页面调整选择器
        )

    # 执行JS,将该元素滚动到视口中间
    driver.execute_script("arguments[0].scrollIntoView({behavior: 'smooth', block: 'center'});", development_title)
    # behavior: 'smooth' 可实现平滑滚动(但取决于浏览器支持)
    # block: 'center' 将元素滚动到视口中央
    print("已滚动到‘发展历程’章节")

except Exception as e:
    print(f"未找到‘发展历程’章节或滚动失败: {e}")
    # 备选方案:滚动到中间位置
    mid_point = total_height // 2
    driver.execute_script(f"window.scrollTo(0, {mid_point});")
    print("已滚动到页面中部")

#强制在页面停留3秒
time.sleep(3)

(6)滑动到动态元素页面可见

当我们需要定位的元素是动态元素,或者我们不确定它在哪时,可以先找到这个元素然后再使用JS操作。

target = driver.find_element_by_id('id')

driver.execute_script("arguments[0].scrollIntoView();", target)

(7)判断元素是否存在

def is_element_exist(browser,xpath):
	try:
		element=browser.find_element(by=By.XPATH,value=xpath)
		flag=True
	except:
		flag=False
	return flag

9.xpath方法

XPath是一门在XML文档中查找信息的语言,被用于在XML和HTML文档中通过元素和属性进行导航。

七种节点类型

元素如 <book><title>
属性如 id="main"
文本元素中的文本内容
注释<!-- 注释 -->
命名空间节点
处理指令
文档根节点

(1)XPath路径表达式

表达式含义
nodename选取此节点的所有子节点(div)
/从根节点选取
//选择任意位置的某个节点
.选取当前节点
选取当前节点的父节点
@选取属性

(2)XPath语法通配符

通配符含义
*匹配任何元素节点
@*匹配任何属性节点
node()匹配任何类型节点

(3)谓语

用于查找特定节点或包含特定值的节点,写在方括号中:

//div[@class='content']  // 选择 class 属性为 content 的 div
//ul/li[1]              // 选择每个 ul 的第一个 li 子元素
//a[contains(@href,'example')]  // 选择 href 属性包含 'example' 的 a 标签

(4)基本Xpath定位

A.通过标签名定位
# 定位所有 div 元素
driver.find_element(By.XPATH, "//div")

# 定位所有 input 元素
driver.find_element(By.XPATH, "//input")
B.通过ID定位
# 定位 ID 为 "username" 的元素
driver.find_element(By.XPATH, "//*[@id='username']")

# 定位 ID 为 "password" 的 input 元素
driver.find_element(By.XPATH, "//input[@id='password']")
C.通过 class 定位
# 定位 class 为 "form-control" 的元素
driver.find_element(By.XPATH, "//*[@class='form-control']")

# 定位 class 包含 "btn" 的元素
driver.find_element(By.XPATH, "//*[contains(@class, 'btn')]")

# 定位 class 同时包含 "btn" 和 "btn-primary" 的元素
driver.find_element(By.XPATH, "//*[contains(@class, 'btn') and contains(@class, 'btn-primary')]")

(5)使用文本内容定位

A.精确文本匹配
# 定位文本内容为 "登录" 的按钮
driver.find_element(By.XPATH, "//button[text()='登录']")

# 定位文本内容为 "忘记密码?" 的链接
driver.find_element(By.XPATH, "//a[text()='忘记密码?']")
B.部分文本匹配
# 定位文本包含 "用户" 的元素
driver.find_element(By.XPATH, "//*[contains(text(), '用户')]")

# 定位文本以 "欢迎" 开头的元素
driver.find_element(By.XPATH, "//*[starts-with(text(), '欢迎')]")

# 定位文本以 "!" 结尾的元素
driver.find_element(By.XPATH, "//*[substring(text(), string-length(text())) = '!']")

(6)使用属性定位

A.属性组合
# 定位 type="text" 且 name="username" 的 input 元素
driver.find_element(By.XPATH, "//input[@type='text' and @name='username']")

# 定位 type="submit" 或 type="button" 的 input 元素
driver.find_element(By.XPATH, "//input[@type='submit' or @type='button']")
B.属性值部分匹配
# 定位 name 属性以 "user" 开头的元素
driver.find_element(By.XPATH, "//*[starts-with(@name, 'user')]")

# 定位 name 属性以 "name" 结尾的元素
driver.find_element(By.XPATH, "//*[ends-with(@name, 'name')]")  # 注意:ends-with 是 XPath 2.0 函数,可能不被所有浏览器支持

# 定位 href 属性包含 "login" 的元素
driver.find_element(By.XPATH, "//*[contains(@href, 'login')]")

(7)层级关系定位

A.父子关系
# 定位 id 为 "container" 的 div 下的所有 input 元素
driver.find_element(By.XPATH, "//div[@id='container']//input")

# 定位直接子元素
driver.find_element(By.XPATH, "//form/input")  # form 的直接子 input 元素
B.兄弟关系
# 定位紧随 h2 标题后的第一个 p 元素
driver.find_element(By.XPATH, "//h2/following-sibling::p[1]")

# 定位在 p 元素之前的所有 h2 元素
driver.find_element(By.XPATH, "//p/preceding-sibling::h2")
C.父元素
# 定位包含特定 span 的 div 父元素
driver.find_element(By.XPATH, "//span[text()='详情']/parent::div")

(8)索引元素

# 定位第二个 div 元素
driver.find_element(By.XPATH, "(//div)[2]")

# 定位表格中的第三行
driver.find_element(By.XPATH, "//table//tr[3]")

# 定位最后一个 div 元素
driver.find_element(By.XPATH, "(//div)[last()]")

(9)模糊定位

A.使用contains() 包含函数,文本包含某个词语
contains(str1, str2): 判断 str1 是否包含 str2
# 定位文本包含 "用户" 的元素
driver.find_element(By.XPATH, "//*[contains(text(), '用户')]")
B.使用starts-with() 包含函数
starts-with(str1, str2): 判断 str1 是否以 str2 开头
# 定位文本以 "欢迎" 开头的元素
driver.find_element(By.XPATH, "//*[starts-with(text(), '欢迎')]")
C.使用count() 包含函数
count(node-set): 计算节点数量
D.使用last() 包含函数
last(): 返回最后一个节点
E.使用position() 包含函数
position(): 返回节点位置

(10)逻辑定位

使用逻辑运算符 – and、or;可以根据一个元素的多个属性进行定位,确保唯一性

(11)轴定位

轴定位是根据父节点,兄弟节点等节点来定位本节点,使用语法: 轴名称 :: 节点名称,使用较多场景:页面显示为一个表格样式的数据列。

描述   表达式
定位当前节点后的所有节点   //标签名[@属性=属性值]/follow::标签名[@属性=属性值]
定位同一节点后的所有同级节点 //标签名[@属性=属性值]/follow-sibling::标签名[@属性=属性值]
定位当前节点的所有子节点 //标签名[@属性=属性值]/child::标签名[@属性=属性值]
定位当前节点前的所有节点//标签名[@属性=属性值]/preceding::标签名[@属性=属性值]
定位同一个节点前的所有同级节点//标签名[@属性=属性值]/preceding-sibling::标签名[@属性=属性值]
定位当前节点的所有父节点//标签名[@属性=属性值]/parent::标签名[@属性=属性值]
定位当前节点的所有祖父节点//标签名[@属性=属性值]/ancestor::标签名[@属性=属性值]

XPath 最佳实践

1.优先使用 ID 或唯一属性://*[@id="uniqueId"] 比 //div/div/div[3] 更可靠

2.避免过度复杂的路径:太长的路径容易因页面结构变化而失效

3.使用 contains 处理动态类名://div[contains(@class,'product')]

4.结合 CSS 选择器:某些场景下 CSS 选择器可能更简洁

5.测试 XPath 表达式:先在浏览器控制台测试再写入代码

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值