爬虫005----Selenium框架
在总结爬虫 🕷 框架之前,先总结一下selenium框架,也可以说是selenium库,在自动化测试中是老生常谈了(长时间⌛️不用,已经忘记了,实际测试工作中做UI自动化的也很少了,上次搞UI自动化框架还是三年前)。但是爬虫中可能会用到,所以总结复习📒一下
1. 介绍
Selenium 广泛用于网络爬虫(Web Scraping),尤其是在处理动态网页和需要与用户界面交互的场景中。与常见的请求库(如 requests)相比,Selenium 能够模拟用户与浏览器交互,因此可以抓取 JavaScript 动态生成的内容。
2. 官方文档和使用
https://www.w3cschool.cn/selenium2/selenium2-52lc3g7e.html
直接给w3c的文档吧,毕竟是中文,不想找官网文档了,可能还不支持中文翻译🤣
# 安装selenium
pip install selenium# 需要配套一个浏览器驱动,根据浏览器的版本选择合适的驱动进行下载安装
# 那个经常使用的浏览器驱动下载页面已经无法访问了,可以找其他方式,就不去找了# 导包
from selenium import webdriver
一个☝️小例子🌰
import time
from selenium import webdriver
from selenium.webdriver.service import Service
from selenium.webdriver.options import Options# 创建options对象
chrome_options = Options()# 指定chromedriver路径
path_to_chromedriver = r'../chromedriver.exe'# 使用service创建实例
service = Service(path_to_chromedriver)
driver = webdriver.Chrome(service=service, options=options)# 链接url
driver.get("https://jd.com/")
time.sleep(10)
对上述示例的总结📒:
- 我为了省事,将驱动直接放进项目文件夹📂目录下而且没有配置环境变量,所以需要指定路径,如果设置了环境变量就不需要这么麻烦去指定路径了,直接调用webdriver即可
- 我使用了强制等待,反正是小示例,实际工作中尽量避免,强制等待会造成资源浪费,而且不优雅,推荐selenium自带的等待⌛️方式,以显示等待最优
2.1 浏览器驱动安装步骤
-
下载浏览器驱动,按照浏览器最新版本下载对应的驱动
没有对应的版本的话,一般下载最新版,最新版驱动能兼容之前版本 -
将chromedriver.exe文件放入python路径下
不知道python安装路径的话,打开cmd窗口,输入where python,就看到了
-
验证:打开cmd窗口,输入chromedriver -version,如果出现对应的版本号,则证明驱动安装完毕
安装完毕之后,就不需要指定路径了,直接调用webdriver即可,如下示例(现在的selenium不需要手动close)
import timefrom selenium import webdriverdriver = webdriver.Chrome()
driver.get('https://www.baidu.com')
time.sleep(5)
3. selenium元素定位(8大定位方式)
selenium 4往后的版本,废弃了find_element_by方式,改用find_element()方式进行元素定位,使用前需导入By方法(from selenium.webdriver.common.by import By)
定位方式 | 解释 | 🌰 |
---|---|---|
By.ID | ID定位 | element = driver.find_element(By.ID, 'element_id') |
By.NAME | 名称定位 | element = driver.find_element(By.NAME, 'element_name') |
By.CLASS_NAME | 类名定位 | element = driver.find_element(By.CLASS_NAME, 'class_name') |
By.TAG_NAME | 标签名定位 | element = driver.find_element(By.TAG_NAME, 'tag_name') |
By.LINK_TEXT | 链接文本定位,只适用于a标签 | element = driver.find_element(By.LINK_TEXT, 'Link Text') |
By.PARTIAL_LINK_TEXT | 部分链接文本定位 | element = driver.find_element(By.PARTIAL_LINK_TEXT, 'Partial Text') |
By.CSS_SELECTOR | CSS 选择器定位 | element = driver.find_element(By.CSS_SELECTOR, 'div.class_name #element_id') |
By.XPATH | XPath 定位 | element = driver.find_element(By.XPATH, '//div[@class="class_name"]') |
4. 不同前端元素定位
练习网址🌍:https://element.eleme.cn/#/zh-CN/component/radio,https://iviewui.com/view-ui-plus/guide/introduce,https://sahitest.com/demo/,使用里面的组件进行定位练习
4.1 Radio单选框
import timefrom selenium import webdriver
from selenium.webdriver.common.by import Bydriver = webdriver.Chrome()
driver.get('https://iviewui.com/view-ui-plus/component/form/radio')
driver.maximize_window()driver.find_elements(By.XPATH, '//input[@class="ivu-radio-input" and @type="radio"]')[1].click()
time.sleep(2)
driver.find_elements(By.XPATH, '//input[@class="ivu-radio-input" and @type="radio"]')[2].click()
time.sleep(2)
driver.find_elements(By.XPATH, '//input[@class="ivu-radio-input" and @type="radio"]')[3].click()
time.sleep(2)driver.find_element(By.XPATH, '//span[text()="Android"]').click()
time.sleep(2)
4.2 CheckBox多选框
import timefrom selenium import webdriver
from selenium.webdriver.common.by import Bydriver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://iviewui.com/view-ui-plus/component/form/checkbox")# //input[@type="checkbox" and @value="twitter"]
driver.find_element(By.XPATH, '//input[@type="checkbox" and @value="twitter"]').click()
time.sleep(2)
driver.find_element(By.XPATH, '//input[@type="checkbox" and @value="twitter"]').click()
time.sleep(2)
driver.find_element(By.XPATH, '//input[@type="checkbox" and @value="facebook"]').click()
time.sleep(2)
driver.find_element(By.XPATH, '//input[@type="checkbox" and @value="facebook"]').click()
time.sleep(2)
driver.find_element(By.XPATH, '//input[@type="checkbox" and @value="github"]').click()
time.sleep(2)
driver.find_element(By.XPATH, '//input[@type="checkbox" and @value="github"]').click()
time.sleep(2)
driver.find_element(By.XPATH, '//input[@type="checkbox" and @value="snapchat"]').click()
time.sleep(2)
driver.find_element(By.XPATH, '//input[@type="checkbox" and @value="snapchat"]').click()
time.sleep(2)
driver.find_element(By.XPATH, '//span[text()="Twitter"]').click()
time.sleep(2)
4.3 Select选择器
4.3.1 使用Select类对select进行定位
select = Select(driver.find_element(By.xx, "xx"))
- select.select_by_index(int): 根据index下标获取内容
- select.select_by_value(“value值”): 根据value值来获取内容
- select.select_by_visible_text(“Cell Phone”): 根据内容获取内容
还有一种情况:select下拉框不是select标签时,可以根据正常普通定位方式进行元素定位
import timefrom selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Selectdriver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://sahitest.com/demo/selectTest.htm")time.sleep(2)select = Select(driver.find_element(By.ID, "s1"))# 根据index下标获取内容
select.select_by_index(1)
time.sleep(2)# 根据value值来获取内容
select.select_by_value("51")
time.sleep(2)# 根据内容获取内容
select.select_by_visible_text("Cell Phone")
time.sleep(2)
4.4 级联选择
其实也就是几个点击事件合在一起,只要找到元素点击一下,再找到元素再点击即可实现
import timefrom selenium import webdriver
from selenium.webdriver.common.by import Bydriver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://iviewui.com/view-ui-plus/component/form/cascader")time.sleep(2)
driver.find_element(By.XPATH, '//input[@class="ivu-input ivu-input-default"]').click()
driver.find_element(By.XPATH, '//li[contains(text(), "北京")]').click()
driver.find_element(By.XPATH, '//li[contains(text(), "王府井")]').click()
time.sleep(2)
4.5 时间选择器
import timefrom selenium import webdriver
from selenium.webdriver.common.by import Bydriver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://iviewui.com/view-ui-plus/component/form/date-picker")
time.sleep(2)driver.find_elements(By.XPATH, '//input[@class="ivu-input ivu-input-default ivu-input-with-suffix"]')[1].send_keys("2025-06-30 - 2025-07-30")
driver.find_element(By.XPATH, '//input[@class="ivu-input ivu-input-default ivu-input-with-suffix"]').send_keys("2025-06-25")
time.sleep(2)
4.6 弹框
- alert:
- driver.switch_to.alert.text:输出弹框的文字
- driver.switch_to.alert.accept():点击确定按钮
- confirm:
- driver.switch_to.alert.text:输出弹框的文字
- driver.switch_to.alert.accept():点击确定按钮
- driver.switch_to.alert.dismiss():点击取消按钮
- prompt:
- driver.switch_to.alert.send_keys(“xxxx”):输入文字
- driver.switch_to.alert.accept():点击确定按钮
- driver.switch_to.alert.dismiss():点击取消按钮
from selenium import webdriver
from selenium.webdriver.common.by import Byimport timedriver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://sahitest.com/demo/alertTest.htm")time.sleep(2)
driver.find_element(By.NAME, "b1").click()# 输入弹框的文字
print(driver.switch_to.alert.text)
time.sleep(2)
# 点击确定按钮
driver.switch_to.alert.accept()
time.sleep(5)
import time
from selenium import webdriver
from selenium.webdriver.common.by import Bydriver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://sahitest.com/demo/confirmTest.htm")time.sleep(2)
driver.find_element(By.NAME, "b1").click()
time.sleep(2)# 获取弹框的文字
print(driver.switch_to.alert.text)
time.sleep(2)# 点击同意
# driver.switch_to.alert.accept()
# time.sleep(2)# 点击取消
driver.switch_to.alert.dismiss()
time.sleep(2)
import time
from selenium import webdriver
from selenium.webdriver.common.by import Bydriver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://sahitest.com/demo/promptTest.htm")time.sleep(2)
driver.find_element(By.NAME, "b1").click()
time.sleep(2)# 输入文字
driver.switch_to.alert.send_keys("测试alert")
time.sleep(2)# 点击同意
driver.switch_to.alert.accept()
time.sleep(2)
4.7 文件上传upload
import os
import time
from selenium import webdriver
from selenium.webdriver.common.by import Bydriver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://sahitest.com/demo/php/fileUpload.htm")time.sleep(2)
upload = driver.find_element(By.ID, "file")filename = os.path.join(os.path.dirname(os.path.realpath(__file__)), "test.txt")upload.send_keys(filename)
time.sleep(2)
driver.find_element(By.NAME, 'submit').click()time.sleep(2)
4.8 iframe框架
- 进入iframe: driver.switch_to.frame(xxx)
可以根据下标进入iframe,也可以根据id和name进入iframe - 退出iframe: driver.switch_to.parent_frame()
- 切换到主页面: driver.switch_to.default_content()
退出iframe可以通过退出函数,也可以使用切换到主页面的方式退出
import time
from selenium import webdriver
from selenium.webdriver.common.by import Bydriver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://sahitest.com/demo/iframesTest.htm")time.sleep(2)driver.find_element(By.ID, 'checkRecord').clear()
driver.find_element(By.ID, 'checkRecord').send_keys("6666")
time.sleep(2)# 用下标进入iframe
# driver.switch_to.frame(1)
# 根据id、name也可以进入iframe
driver.switch_to.frame(driver.find_element(By.CSS_SELECTOR, 'body > iframe'))
time.sleep(2)
# driver.find_element(By.CSS_SELECTOR, 'a[href="LinkTest.htm"]').click()
# driver.find_element(By.ID, 'open-self').click()
time.sleep(2)# 退出iframe
# driver.switch_to.parent_frame()# 切换到主页面
driver.switch_to.default_content()driver.find_element(By.ID, 'checkRecord').clear()
driver.find_element(By.ID, 'checkRecord').send_keys("7777")time.sleep(2)time.sleep(2)
5. 浏览器操作
接下来几部分将总结一家伙driver的常用操作
5.1 最大化窗口
driver.maximize_window()
5.2 最小化窗口
driver.minimize_window()
5.3 设置窗口大小
# 设置窗口大小为1024*768
driver.set_window_size(1024, 768)
5.4 全屏模式
driver.fullscreen_window()
6. 页面导航
6.1 前进和后退
driver.back() # 返回上一个页面
driver.forword() # 前往下一个页面
6.2 刷新页面
driver.refresh()
6.3 切换窗口和标签页
6.3.1 切换窗口 switch_to.windows()
from selenium import webdriverdriver = webdriver.Chrome()# 打开第一个窗口
driver.get("https://example.com")# 打开第二个窗口
driver.execute_script("window.open('https://example.org');")# 获取所有窗口句柄
window_handles = driver.window_handles# 切换到第二个窗口
driver.switch_to.window(window_handles[1])# 在第二个窗口中操作
print(driver.title)# 切换回第一个窗口
driver.switch_to.window(window_handles[0])
6.4 切换标签页
切换标签页与切换窗口类似,因为每个标签页都是一个独立的窗口句柄
from selenium import webdriver# 设置正确的驱动路径
driver = webdriver.Chrome()# 打开第一个标签页
driver.get("https://example.com")# 打开第二个标签页
driver.execute_script("window.open('https://example.org');")# 获取所有标签页句柄
tab_handles = driver.window_handles# 切换到第二个标签页
driver.switch_to.window(tab_handles[1])# 在第二个标签页中操作
print(driver.title)# 切换回第一个标签页
driver.switch_to.window(tab_handles[0])
7 获取页面标题和url
tittle = driver.tittle # 获取页面标题
url = driver.current_url # 获取页面url
8. 动态元素定位技巧
8.1 使用相对路径
可以避免因为元素位置或id变换而导致定位失败
element = driver.find_element(By.XPATH, "//div[@class='dynamic_class']")
8.2 使用部分匹配
例如使用contains函数进行部分匹配
element = driver.find_element(By.XPATH, '//div[contains=(@id), "dynamic_name"]')
8.3 使用等待机制
动态元素可能不会立即出现在桌面上,可以使用等待机制等待元素出现
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ECelement = WebDriverWait(driver, 10).until(EC.presence_of_element_located(By.ID, "dynamic_id"))
8.4 使用JS定位
element = driver.execute_script("return document.querySelector('dynamic_selector');")
9. 等待机制
9.1 隐式等待(implicitly_wait)
9.1.1 什么是隐式等待?
隐式等待是一种全局性的等待机制,它会在查找元素时等待一定的时间。如果在指定的时间内找到了元素,Selenium 会立即继续执行后续操作;如果超时仍未找到元素,则会抛出 NoSuchElementException 异常。
9.1.2 如何使用隐式等待?
隐式等待通过 implicitly_wait() 方法来设置。这个方法只需要调用一次,之后的所有元素查找操作都会遵循这个等待时间。
from selenium import webdriverdriver = webdriver.Chrome()# 设置隐式等待时间为 10 秒
driver.implicitly_wait(10)# 打开网页
driver.get("https://example.com")# 查找元素
element = driver.find_element_by_id("element_id")
9.1.3 隐式等待的优缺点
优点:
- 简单易用,只需设置一次即可应用于所有元素查找操作。
- 适用于大多数简单的场景。
缺点:
3. 全局性等待,可能会导致不必要的等待时间。
4. 无法处理某些复杂的等待条件,例如等待元素变为可点击状态。
9.2. 显式等待(WebDriverWait 和 expected_conditions)
一般工作中基本上使用的是显示等待,因为可能每一次元素定位或页面加载需要的时间不同,如果使用隐式等待或强制等待强行让其等上固定的某个时间,可能会造成资源浪费或者时间不够导致元素未加载出来就结束🔚
9.2.1 什么是显式等待?
显式等待是一种更为灵活的等待机制,它允许你为特定的操作设置等待条件。显式等待通常与 WebDriverWait 类和 expected_conditions 模块一起使用。
9.2.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# 设置正确的驱动路径
driver = webdriver.Chrome()# 打开网页
driver.get("https://example.com")# 设置显式等待,最多等待 10 秒,直到元素出现
element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "element_id"))
)
9.2.3 常用的 expected_conditions
expected_conditions 模块提供了多种预定义的等待条件,以下是一些常用的条件:
- presence_of_element_located: 等待元素出现在 DOM 中。
- visibility_of_element_located: 等待元素出现在 DOM 中并且可见。
- element_to_be_clickable: 等待元素可点击。
- text_to_be_present_in_element: 等待元素的文本包含指定的文本。
9.2.4 显式等待的优缺点
优点:
- 灵活性高,可以为不同的操作设置不同的等待条件。
- 可以处理复杂的等待场景。
缺点:
3. 代码相对复杂,需要更多的代码量。
4. 需要为每个操作单独设置等待条件。
9.3 固定等待(time.sleep)
9.3.1 什么是固定等待?
固定等待是一种最简单的等待机制,它通过 time.sleep() 方法让脚本暂停执行指定的时间。无论页面是否加载完成,脚本都会等待指定的时间后再继续执行。
9.3.2 如何使用固定等待?
实例
import time
from selenium import webdriver# 设置正确的驱动路径
driver = webdriver.Chrome()# 打开网页
driver.get("https://example.com")# 固定等待 5 秒
time.sleep(5)# 查找元素
element = driver.find_element_by_id("element_id")
9.3.3 固定等待的优缺点
优点:
- 简单易用,适用于简单的测试场景。
缺点:
2. 效率低下,可能会导致不必要的等待时间。
3. 无法根据页面加载情况动态调整等待时间。
10. 浏览器Cookies操作
Selenium提供了get_cookies()、add_cookie()、delete_cookie() 等方法来操作浏览器的Cookies
10.1 获取Cookies
get_cookies()
from selenium import webdriverdriver = webdriver.Chrome()# 打开网页
driver.get("https://www.baidu.com")# 获取所有 Cookies
cookies = driver.get_cookies()
print(cookies)
10.2 添加Cookies
add_cookie()
from selenium import webdriverdriver = webdriver.Chrome()# 打开网页
driver.get("https://www.baidu.com")# 添加 Cookie
driver.add_cookie({"name": "test", "value": "123"})# 获取所有 Cookies
cookies = driver.get_cookies()
print(cookies)
10.4 删除cookies
delete_cookie()
from selenium import webdriverdriver = webdriver.Chrome()# 打开网页
driver.get("https://www.baidu.com")# 添加 Cookie
driver.add_cookie({"name": "test", "value": "123"})# 删除 Cookie
driver.delete_cookie("test")# 获取所有 Cookies
cookies = driver.get_cookies()
print(cookies)
11. 执行javascript代码
11.1 执行js代码
execute_script()
from selenium import webdriverdriver = webdriver.Chrome()# 打开网页
driver.get("https://www.baidu.com")# 执行 JavaScript 代码
driver.execute_script("alert('这是一个 JavaScript 弹窗');")
11.2 获取js返回值
from selenium import webdriverdriver = webdriver.Chrome()# 打开网页
driver.get("https://www.baidu.com")# 执行 JavaScript 代码并获取返回值
result = driver.execute_script("return document.title;")
print(result)
12. 鼠标键盘操作
12.1 鼠标操作(ActionChains类)
使用时记得需要先实例化ActionChains对象(action = ActionChains(driver)),导入ActionChains包,from selenium.webdriver.common.action_chains import ActionChains
记得调用perform()函数,操作才会生效✅哈😄
操作系统 | 方法 | 说明 |
---|---|---|
点击 | click(element) click() | 点击指定元素或当前鼠标的位置 |
双击 | double_click(element) doubleclick() | 双击指定元素或当前鼠标的位置 |
右击 | context_click(element) context_click() | 右击指定元素或当前鼠标的位置 |
拖放 | drag_and_drop(source, taeget) | 将源元素拖放到目标元素 |
悬停 | move_to_element(element) | 将鼠标移动到指定元素上 |
按住和释放 | click_and_hold(element) release() | 按住指定元素并释放,用于实现拖拽效果 |
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import Bydriver = webdriver.Chrome()# 打开网页
driver.get("https://www.baidu.com")# 定位元素
element = driver.find_element(By.ID, "kw")# 创建 ActionChains 对象
actions = ActionChains(driver)# 点击操作
actions.click(element).perform()# 双击操作
actions.double_click(element).perform()# 右键点击操作
actions.context_click(element).perform()
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import Bydriver = webdriver.Chrome()# 打开网页
driver.get("https://www.baidu.com")# 定位拖动的元素和目标元素
source_element = driver.find_element(By.ID, "source_element_id")
target_element = driver.find_element(By.ID, "target_element_id")# 创建 ActionChains 对象
actions = ActionChains(driver)# 拖放操作
actions.drag_and_drop(source_element, target_element).perform()
12.2 键盘操作(Keys类)
使用时记得需要先导入Keys模块from selenium.webdriver.common.by import By
操作系统 | 方法 | 说明 |
---|---|---|
输入文本 | send_keys("text") | 向输入框或文本区域输入指定文本 |
按下组合键 | send_keys(Keys.CONTROL + "a") | 模拟按下组合键(ctrl+A) |
按下单个键 | send_keys(Keys.KEY_NAME) | 模拟按下单个键(Enter、Tab等) |
释放按键 | key_up(key) | 释放按下的键 |
import timefrom selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import Bydriver = webdriver.Chrome()# 打开网页
driver.get("https://www.baidu.com")# 定位输入框
input_element = driver.find_element(By.ID, "kw")# 输入内容并发送组合键
input_element.send_keys("Hello, World!")
time.sleep(2)
input_element.send_keys(Keys.CONTROL, 'a') # 全选
time.sleep(2)
input_element.send_keys(Keys.CONTROL, 'c') # 复制
time.sleep(2)
input_element.send_keys(Keys.CONTROL, 'v') # 粘贴time.sleep(2)
13. 无头模式
13.1 介绍
浏览器无头模式可以大大提升selenium操作效率,从而加快自动化测试以及爬虫🐞的效率⇡,看下面的官方解释👇
无头浏览器模式(Headless Mode)是指在没有图形用户界面(GUI)的情况下运行浏览器,换句话说,浏览器在后台运行,不会弹出可见的窗口。
无头浏览器模式通常用于自动化测试、网页抓取、性能测试等场景,因为它可以节省系统资源,并且在没有显示器的服务器上也能正常运行。
-
启用无头模式: 通过 ChromeOptions 或 FirefoxOptions 添加 --headless 参数。
-
优化设置: 禁用 GPU 加速、设置窗口大小等。
-
验证无头模式: 通过打印页面标题或截图验证脚本运行结果。
13.1.1 为什么使用无头浏览器模式?
- 节省资源: 无头模式不需要渲染图形界面,因此可以节省 CPU 和内存资源。
- 提高速度: 由于不需要加载和渲染图形界面,无头模式通常比普通模式更快。
- 适合自动化: 在自动化测试和网页抓取中,无头模式可以避免干扰,并且可以在没有显示器的服务器上运行。
- 便于调试: 在某些情况下,无头模式可以帮助开发者更快地调试和定位问题。
13.1.2 配置实现
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options# 设置 Chrome 无头模式
chrome_options = Options()
chrome_options.add_argument("--headless") # 启用无头模式
chrome_options.add_argument("--disable-gpu") # 禁用 GPU 加速# 创建 WebDriver 实例
driver = webdriver.Chrome(options=chrome_options)# 打开网页
driver.get("https://www.baidu.com")# 打印网页标题
print(driver.title)
selenium常用的就总结到这里,如果UI测试自动化还有pytest库等等,因为这是爬虫板块,就把爬虫可以使用到的总结一下完事🔚,其他的以后再说