杰瑞科技汇

python selenium用法

目录

  1. 环境准备
  2. 第一个 Selenium 脚本
  3. 核心概念:浏览器驱动
  4. 核心操作详解
    • 定位元素
    • 与元素交互
    • 获取元素信息
    • 处理下拉框和弹窗
    • 执行 JavaScript
    • 等待策略
  5. 高级用法
    • 页面截图
    • 录制屏幕
    • 无头模式
  6. 实战案例:爬取知乎热榜
  7. 最佳实践与注意事项

环境准备

在开始之前,你需要确保你的电脑上已经安装了以下软件:

python selenium用法-图1
(图片来源网络,侵删)
  • Python: 建议使用 3.6+ 版本。
  • Chrome 浏览器: Selenium 将控制它。
  • ChromeDriver: 这是 Selenium 控制 Chrome 浏览器的桥梁。

安装 Python 库

打开你的终端或命令提示符,使用 pip 安装 selenium 库:

pip install selenium

下载 ChromeDriver

这是最关键也最容易出错的一步。

  1. 检查 Chrome 版本: 打开 Chrome 浏览器,进入 设置 -> Chrome,记下你的 Chrome 版本号(0.5735.199)。

  2. 下载对应版本的 ChromeDriver:

    python selenium用法-图2
    (图片来源网络,侵删)
    • 访问官方下载地址:https://googlechromelabs.github.io/chrome-for-testing/
    • 找到与你的 Chrome 版本最接近的 chromedriver 版本,推荐下载 win32mac-x64linux64 压缩包。
    • 重要提示: 从 Chrome 115 版本开始,Google 官方推荐使用这个新链接,旧版的 https://chromedriver.chromium.org/downloads 已不再维护。
  3. 配置环境:

    • 方法一 (推荐): 将下载的 chromedriver.exe (Windows) 或 chromedriver (Mac/Linux) 文件放到你的 Python 脚本所在的同一个目录下,这样 Selenium 会自动寻找。
    • 方法二: 将 chromedriver 所在的目录添加到系统的 PATH 环境变量中,这样你可以在任何地方运行它。

第一个 Selenium 脚本

让我们从一个最简单的例子开始:打开 Chrome 浏览器,访问百度,然后关闭。

# 1. 导入 webdriver
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time
# 2. 创建一个 Chrome 浏览器实例
# chromedriver 不在脚本同目录或 PATH 中,需要指定其路径
# driver = webdriver.Chrome(executable_path="path/to/your/chromedriver")
driver = webdriver.Chrome()
# 3. 打开一个网页
driver.get("https://www.baidu.com")
# 4. 打印网页标题
print("页面标题是:", driver.title)
# 5. 让浏览器窗口等待 5 秒,方便观察
time.sleep(5)
# 6. 关闭浏览器
driver.quit()

运行这个脚本,你会看到一个 Chrome 窗口自动打开,访问百度,5 秒后自动关闭。


核心概念:浏览器驱动

  • WebDriver: Selenium 的核心,是一个浏览器自动化 API,它就像是你的 Python 代码和浏览器之间的“翻译官”。
  • 浏览器驱动: 每种浏览器(Chrome, Firefox, Edge 等)都有自己的驱动程序,Chrome 使用 ChromeDriver,Firefox 使用 GeckoDriver,你的 Python 代码通过 WebDriver 调用驱动程序,再由驱动程序去控制具体的浏览器。

核心操作详解

1 定位元素

自动化测试的核心就是找到页面上的元素(如按钮、输入框、链接),然后对它们进行操作,Selenium 提供了 8 种定位方式,最常用的前三种:

定位方式 Python 方法 描述 示例
ID find_element(By.ID, "value") 通过元素的 id 属性定位,最快最可靠 find_element(By.ID, "kw")
XPath find_element(By.XPATH, "value") 通过路径表达式定位,非常强大和灵活 find_element(By.XPATH, '//input[@id="kw"]')
CSS Selector find_element(By.CSS_SELECTOR, "value") 通过 CSS 选择器定位,速度也很快,推荐使用 find_element(By.CSS_SELECTOR, "#kw")
Name find_element(By.NAME, "value") 通过 name 属性定位 find_element(By.NAME, "wd")
Tag Name find_element(By.TAG_NAME, "value") 通过 HTML 标签名定位(如 div, input find_element(By.TAG_NAME, "input")
Class Name find_element(By.CLASS_NAME, "value") 通过 class 属性定位 find_element(By.CLASS_NAME, "s_ipt")
Link Text find_element(By.LINK_TEXT, "value") 通过完整的链接文本定位 <a> find_element(By.LINK_TEXT, "新闻")
Partial Link Text find_element(By.PARTIAL_LINK_TEXT, "value") 通过部分链接文本定位 <a> find_element(By.PARTIAL_LINK_TEXT, "闻")

注意: find_element (单数) 只返回第一个匹配的元素,如果找不到会抛出 NoSuchElementException 异常,如果需要查找所有元素,请使用 find_elements (复数),它返回一个列表。

2 与元素交互

找到元素后,你就可以对它们进行操作了。

# 假设 driver 已经打开百度
# 定位搜索框
search_box = driver.find_element(By.ID, "kw")
# 1. 在搜索框中输入内容
search_box.send_keys("Selenium 教程")
# 2. 模拟按下回车键
search_box.send_keys(Keys.ENTER)
# 或者定位“百度一下”按钮并点击
# search_button = driver.find_element(By.ID, "su")
# search_button.click()

3 获取元素信息

操作之后,通常需要获取一些信息来验证结果。

# 获取元素的文本内容
element = driver.find_element(By.ID, "su")
print("按钮文本:", element.text)
# 获取元素的属性值
print("按钮的 type 属性:", element.get_attribute("type"))
# 获取元素的标签名
print("按钮的标签名:", element.tag_name)

4 处理下拉框和弹窗

  • 下拉框: 使用 Select 类。

    from selenium.webdriver.support.ui import Select
    # 假设有一个 id 为 "country" 的下拉框
    select = Select(driver.find_element(By.ID, "country"))
    # 通过索引选择 (从 0 开始)
    select.select_by_index(1)
    # 通过 value 值选择
    select.select_by_value("us")
    # 通过可见文本选择
    select.select_by_visible_text("China")
  • 弹窗:

    • 警告框: driver.switch_to.alert.accept() (点击确定) / dismiss() (点击取消)
    • 确认框: 同上
    • 提示框: driver.switch_to.alert.send_keys("输入文本") 后再 accept()

5 执行 JavaScript

Selenium 可以直接在浏览器中执行任意 JavaScript 代码,这非常强大。

# 滚动到页面底部
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# 获取页面某个元素的文本 (比 find_element 更直接)
element_text = driver.execute_script("return document.getElementById('kw').value;")
print("通过 JS 获取的搜索框内容:", element_text)

6 等待策略

这是 Selenium 自动化中最重要的概念之一,如果页面元素加载需要时间,而你的代码立即去查找它,很可能会失败,因为元素还没出现。

  • 强制等待 (不推荐): time.sleep(5)

    • 缺点: 固定等待 5 秒,无论元素是否已经加载好,效率低下。
  • 隐式等待 (全局等待):

    # 设置一个全局等待时间,10 秒
    driver.implicitly_wait(10) 
    # 之后所有的 find_element 操作都会等待最多 10 秒
    # 如果元素在 10 秒内出现,立即继续执行;10 秒后还没出现,则抛出异常
    • 缺点: 只对 find_element 有效,并且一旦设置,全局生效,无法针对特定元素设置不同的等待时间。
  • 显式等待 (强烈推荐): 针对特定元素设置等待条件,最灵活、最精确。

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    # 等待最多 10 秒,直到 id 为 "myDynamicElement" 的元素出现
    try:
        element = WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.ID, "myDynamicElement"))
        )
        print("元素已找到!")
    except Exception as e:
        print("元素在指定时间内未找到:", e)
    # 等待元素可被点击
    # WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "submit-button"))).click()

    常用的 expected_conditions:

    • EC.presence_of_element_located: 元素出现在 DOM 中,不一定可见。
    • EC.visibility_of_element_located: 元素可见。
    • EC.element_to_be_clickable: 元素可被点击。
    • EC.title_contains: 标题包含特定文本。

高级用法

1 页面截图

# 截取整个浏览器窗口的截图
driver.save_screenshot("baidu_screenshot.png")
# 截取某个特定元素
element = driver.find_element(By.ID, "kw")
element.screenshot("search_box_screenshot.png")

2 录制屏幕

需要安装 selenium-screen-recorder 库。

pip install selenium-screen-recorder
from screen_recorder import ScreenRecorder
# 创建录制器实例
recorder = ScreenRecorder()
# 开始录制
recorder.start("my_recording.mp4")
# ... 你的自动化操作 ...
# 停止录制
recorder.stop()

3 无头模式

在不显示浏览器界面的情况下运行脚本,速度更快,适合在服务器上运行。

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
# 创建 Chrome 选项对象
chrome_options = Options()
# 添加无头模式参数
chrome_options.add_argument("--headless")
# 还可以设置窗口大小
chrome_options.add_argument("--window-size=1920,1080")
# 使用选项创建浏览器实例
driver = webdriver.Chrome(options=chrome_options)
driver.get("https://www.baidu.com")
print("无头模式下页面标题:", driver.title)
driver.quit()

实战案例:爬取知乎热榜

目标:打开知乎热榜,获取前 5 条热榜标题、热度、链接并保存到 CSV 文件。

import csv
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager # 自动管理驱动
# 自动下载并管理 ChromeDriver
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
try:
    driver.get("https://www.zhihu.com/hot")
    driver.implicitly_wait(5) # 设置一个隐式等待作为保底
    # 知乎热榜的标题、链接、热度都在一个 <div class="HotItem-item"> 容器内
    hot_items = driver.find_elements(By.CSS_SELECTOR, "div.HotItem-item")
    data_to_save = []
    for item in hot_items[:5]: # 只取前5条
        # 标题和链接在 <a> 标签内
        title_element = item.find_element(By.CSS_SELECTOR, "a.HotItem-title")
        title = title_element.text
        link = title_element.get_attribute("href")
        # 热度在 <span class="HotItem-metrics"> 内
        heat_element = item.find_element(By.CSS_SELECTOR, "span.HotItem-metrics")
        heat = heat_element.text
        data_to_save.append([title, heat, link])
        print(f"标题: {title}, 热度: {heat}, 链接: {link}")
    # 保存到 CSV 文件
    with open("zhihu_hot.csv", "w", newline="", encoding="utf-8-sig") as f:
        writer = csv.writer(f)
        writer.writerow(["标题", "热度", "链接"]) # 写入表头
        writer.writerows(data_to_save) # 写入数据
    print("\n数据已成功保存到 zhihu_hot.csv")
finally:
    # 无论是否发生异常,最后都要关闭浏览器
    driver.quit()

最佳实践与注意事项

  1. 显式优先: 优先使用 WebDriverWait (显式等待),避免 time.sleep()implicitly_wait

  2. 稳定的定位器: 优先使用 IDCSS Selector,它们比 XPath 更稳定,因为 XPath 依赖 HTML 的层级结构,容易因页面结构变化而失效。

  3. try...finallywith 语句: 确保浏览器在任何情况下都能被正确关闭,否则会占用大量内存和 CPU。

  4. 元素定位优化: 如果一个元素难以定位,可以尝试先定位其父元素,再从父元素中查找子元素,这样更稳定。

    parent = driver.find_element(By.ID, "parent-container")
    child = parent.find_element(By.CLASS_NAME, "child-class")
  5. 处理 iframe: 如果目标元素在 <iframe> 内,必须先切换到该 iframe,才能定位到里面的元素。

    # 切换到 iframe (可以通过 id, name, 或 WebElement 定位)
    driver.switch_to.frame("my_iframe_id")
    # 现在可以操作 iframe 内的元素了
    element_in_iframe = driver.find_element(By.ID, "element_id")
    # 操作完成后,切回主页面 (非常重要!)
    driver.switch_to.default_content()
  6. 反爬虫: 大量、频繁的自动化操作可能会被网站识别为爬虫,可以采取以下措施:

    • 控制速度: 在操作之间加入合理的随机延迟。
    • 使用代理: IP 被封时使用代理 IP。
    • 模拟人类行为: 随机移动鼠标、滚动页面等(Selenium ActionChains)。
    • 使用 Cookies: 登录后保存 Cookies,下次直接加载,避免重复登录。
  7. 驱动管理: 使用 webdriver-manager 这样的库可以自动为你下载和管理正确版本的浏览器驱动,避免手动下载和配置的麻烦。

希望这份详细的教程能帮助你全面掌握 Python Selenium 的用法!

分享:
扫描分享到社交APP
上一篇
下一篇