python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python Selenium模拟浏览器

从入门到精通解析Python Selenium如何模拟浏览器操作

作者:爱吃提升

Selenium是一款开源的自动化测试工具,核心优势在于能模拟真实用户操作浏览器,下面小编就来和大家详细讲讲Python Selenium如何模拟浏览器的相关操作吧

Selenium是一款开源的自动化测试工具,核心优势在于能模拟真实用户操作浏览器(如点击、输入、滚动),并渲染动态加载的网页内容(解决Requests库无法爬取JS动态数据的问题)。

一、Selenium入门准备:环境搭建与核心原理

1. 核心原理

Selenium通过“浏览器驱动(Driver)”与浏览器通信:Python代码发送操作指令→Driver解析指令→浏览器执行操作并返回渲染后的页面数据,完美适配JS动态渲染的网页(如Ajax加载、Vue/React前端页面)。

2. 环境安装

(1)安装Selenium库

# 安装最新版Selenium
pip install selenium

关键步骤

查看浏览器版本(如Chrome:设置→关于Chrome,查看版本号);

下载对应版本的驱动(版本号需完全匹配,如Chrome 120.x对应ChromeDriver 120.x);

配置驱动路径:

3. 验证环境

# 导入Selenium核心模块
from selenium import webdriver
from selenium.webdriver.chrome.service import Service

# 手动指定ChromeDriver路径
driver_path = "C:/chromedriver.exe"  # Windows路径示例
# 初始化浏览器对象
driver = webdriver.Chrome(service=Service(driver_path))
# 打开测试网页
driver.get("https://www.baidu.com")
# 打印网页标题(输出“百度一下,你就知道”则环境正常)
print(driver.title)
# 关闭浏览器
driver.quit()

二、Selenium基础操作:浏览器与页面控制

1. 浏览器核心操作

操作代码示例说明
打开网页driver.get("https://www.xxx.com")加载目标URL
刷新页面driver.refresh()模拟浏览器刷新
前进/后退driver.forward() / driver.back()模拟浏览器前进/后退按钮
窗口最大化driver.maximize_window()避免元素因窗口过小无法定位
设置窗口大小driver.set_window_size(1920, 1080)自定义窗口分辨率
获取当前URLdriver.current_url查看当前页面URL(验证跳转是否成功)
获取页面源码driver.page_source获取渲染后的完整HTML源码(含JS动态内容)

2. 等待机制:解决元素加载延迟问题

网页动态加载时,直接定位元素会因“元素未加载完成”报错,Selenium提供3种等待方式:

(1)强制等待(不推荐)

import time
# 强制等待3秒(无论元素是否加载完成)
time.sleep(3)

(2)隐式等待(全局生效)

# 设置隐式等待:最长等待10秒,元素加载完成则立即执行
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

# 等待“百度搜索框”可见,最长等待10秒
wait = WebDriverWait(driver, 10)
search_box = wait.until(
    EC.visibility_of_element_located((By.ID, "kw"))
)

常用等待条件

三、核心技能:元素定位(爬取/操作的关键)

元素定位是Selenium的核心,需根据网页结构选择最优定位方式,优先选择唯一标识(ID、Name),其次选择XPath/CSS选择器。

1. 8种定位方式(按优先级排序)

定位方式代码示例适用场景
ID定位driver.find_element(By.ID, "kw")元素有唯一ID(如百度搜索框id=“kw”)
Name定位driver.find_element(By.NAME, "wd")元素有唯一Name属性
Class定位driver.find_element(By.CLASS_NAME, "s_ipt")元素Class属性唯一
Tag定位driver.find_element(By.TAG_NAME, "input")标签唯一(如页面唯一的input框)
Link文本定位driver.find_element(By.LINK_TEXT, "新闻")精准匹配超链接文本
部分Link文本driver.find_element(By.PARTIAL_LINK_TEXT, "新")模糊匹配超链接文本
XPath定位driver.find_element(By.XPATH, '//*[@id="kw"]')无唯一属性时,万能定位方式
CSS选择器driver.find_element(By.CSS_SELECTOR, "#kw")定位效率高于XPath,推荐使用

2. 实战:XPath/CSS选择器高级用法

(1)XPath定位(万能且灵活)

# 绝对路径(不推荐,页面结构变化易失效)
driver.find_element(By.XPATH, "/html/body/div[1]/div[2]/input")
# 相对路径+属性(推荐)
driver.find_element(By.XPATH, '//input[@id="kw"]')
# 包含文本的元素
driver.find_element(By.XPATH, '//a[contains(text(), "百度首页")]')
# 父节点定位子节点
driver.find_element(By.XPATH, '//div[@class="s_form"]/input')

(2)CSS选择器(效率更高)

# ID选择器
driver.find_element(By.CSS_SELECTOR, "#kw")
# Class选择器
driver.find_element(By.CSS_SELECTOR, ".s_ipt")
# 属性选择器
driver.find_element(By.CSS_SELECTOR, 'input[name="wd"]')
# 层级选择器
driver.find_element(By.CSS_SELECTOR, "div.s_form > input")

3. 批量定位元素

使用find_elements()(复数形式)获取多个元素,返回列表:

# 获取页面所有超链接
links = driver.find_elements(By.TAG_NAME, "a")
for link in links:
    print(link.get_attribute("href"))  # 打印链接地址

四、模拟用户操作:输入、点击、滚动等

1. 输入与清空

# 定位搜索框并输入内容
search_box = driver.find_element(By.ID, "kw")
search_box.send_keys("Selenium教程")  # 输入文本
search_box.clear()  # 清空输入框
search_box.send_keys("Python爬虫")  # 重新输入

2. 点击操作

# 点击搜索按钮
search_btn = driver.find_element(By.ID, "su")
search_btn.click()

# 模拟回车键(替代点击按钮)
search_box.send_keys(Keys.ENTER)

3. 滚动页面

from selenium.webdriver.common.keys import Keys

# 方式1:模拟键盘向下滚动(PageDown)
driver.find_element(By.TAG_NAME, "body").send_keys(Keys.PAGE_DOWN)

# 方式2:JS脚本滚动(精准控制)
# 滚动到页面底部
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# 滚动到指定元素位置
target = driver.find_element(By.ID, "target_id")
driver.execute_script("arguments[0].scrollIntoView();", target)

4. 处理弹窗

(1)alert弹窗(系统弹窗)

# 等待弹窗出现
alert = WebDriverWait(driver, 10).until(EC.alert_is_present())
# 获取弹窗文本
print(alert.text)
# 确认弹窗
alert.accept()
# 取消弹窗(仅confirm弹窗可用)
# alert.dismiss()

(2)iframe框架(嵌套页面)

需先切换到iframe,才能定位内部元素:

# 方式1:通过ID切换
driver.switch_to.frame("iframe_id")
# 方式2:通过元素定位切换
iframe = driver.find_element(By.XPATH, '//iframe[@name="iframe_name"]')
driver.switch_to.frame(iframe)

# 操作iframe内元素
driver.find_element(By.ID, "inner_btn").click()

# 切回主页面
driver.switch_to.default_content()

5. 处理下拉框

from selenium.webdriver.support.ui import Select

# 定位下拉框
select = Select(driver.find_element(By.ID, "select_id"))
# 方式1:按索引选择(从0开始)
select.select_by_index(1)
# 方式2:按值选择(option的value属性)
select.select_by_value("option_value")
# 方式3:按文本选择
select.select_by_visible_text("选项文本")

# 获取所有选项
options = select.options
for option in options:
    print(option.text)

五、进阶技巧:反爬规避与效率优化

1. 配置无界面模式(后台运行)

from selenium.webdriver.chrome.options import Options

# 创建Chrome配置对象
chrome_options = Options()
# 开启无界面模式
chrome_options.add_argument("--headless=new")
# 禁用GPU(避免无界面模式报错)
chrome_options.add_argument("--disable-gpu")

# 初始化浏览器(带配置)
driver = webdriver.Chrome(
    service=Service(driver_path),
    options=chrome_options
)

2. 规避浏览器指纹检测

# 禁用自动化提示(去除“Chrome正受到自动测试软件控制”)
chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
chrome_options.add_experimental_option('useAutomationExtension', False)
# 禁用Blink运行时功能
chrome_options.add_argument("--disable-blink-features=AutomationControlled")
# 设置用户代理(UA)
chrome_options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36")
# 移除webdriver属性(关键反爬)
driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")

3. 多标签页/窗口操作

# 打开新标签页
driver.execute_script("window.open('https://www.taobao.com')")
# 获取所有标签页句柄
windows = driver.window_handles
# 切换到第二个标签页
driver.switch_to.window(windows[1])
# 关闭当前标签页
driver.close()
# 切回第一个标签页
driver.switch_to.window(windows[0])

4. 截图与日志

# 页面全屏截图
driver.save_screenshot("page.png")
# 元素截图
element = driver.find_element(By.ID, "kw")
element.screenshot("element.png")

# 查看浏览器日志(排查错误)
logs = driver.get_log("browser")
for log in logs:
    print(log)

六、实战案例:爬取JS动态加载的商品数据

以某电商平台商品列表为例(JS动态加载),爬取商品名称、价格、销量:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
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_path = "C:/chromedriver.exe"
# 初始化浏览器
driver = webdriver.Chrome(service=Service(driver_path))
driver.maximize_window()
driver.implicitly_wait(10)

try:
    # 打开商品列表页
    driver.get("https://xxx.com/goods-list")
    
    # 滚动页面加载更多商品(模拟翻页)
    for i in range(3):  # 滚动3次
        # 滚动到页面底部
        driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
        time.sleep(2)  # 等待数据加载
    
    # 定位所有商品元素
    goods_list = WebDriverWait(driver, 10).until(
        EC.presence_of_all_elements_located((By.CLASS_NAME, "goods-item"))
    )
    
    # 解析商品信息
    for goods in goods_list:
        # 商品名称
        name = goods.find_element(By.CLASS_NAME, "goods-name").text
        # 商品价格
        price = goods.find_element(By.CLASS_NAME, "goods-price").text
        # 商品销量
        sales = goods.find_element(By.CLASS_NAME, "goods-sales").text
        
        print(f"名称:{name},价格:{price},销量:{sales}")

finally:
    # 关闭浏览器
    driver.quit()

七、常见问题与避坑指南

  1. 驱动版本不匹配:报错“SessionNotCreatedException”,需下载与浏览器版本完全一致的驱动;
  2. 元素定位失败
    • 检查元素是否在iframe内(需先切换iframe);
    • 检查元素是否动态加载(用显式等待替代强制等待);
    • 避免使用绝对XPath(页面结构变化易失效);
  3. 反爬检测:被网站识别为爬虫时,添加UA、禁用自动化提示、随机滚动/点击间隔;
  4. 内存泄漏:务必用driver.quit()关闭浏览器(而非driver.close()),避免进程残留;
  5. 中文乱码:爬取的文本乱码时,添加编码设置:driver.execute_script("document.charset='utf-8'")

到此这篇关于从入门到精通解析Python Selenium如何模拟浏览器操作的文章就介绍到这了,更多相关Python Selenium模拟浏览器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文