杰瑞科技汇

Python Splinter 文档怎么快速上手?

Splinter Python 库完整指南

Splinter 的核心思想是提供一个统一的接口,让你可以使用不同的浏览器后端(如 Chrome, Firefox, PhantomJS 等)来执行常见的 Web 自动化任务,如点击、填写表单、导航等,而无需关心不同浏览器之间的底层差异。

Python Splinter 文档怎么快速上手?-图1
(图片来源网络,侵删)

目录

  1. 安装与环境配置
  2. 核心概念
    • Driver (浏览器驱动)
    • Browser (浏览器实例)
  3. 基本操作
    • 打开与关闭浏览器
    • 导航
    • 与页面交互
    • 查找元素
    • 处理表单
    • 执行 JavaScript
    • 处理弹窗和警告
    • 页面截图
  4. 高级功能
    • 等待元素
    • 文件上传
    • Cookies 处理
    • 页面源码与标题
  5. 常用 Driver 介绍
    • ChromeDriver
    • Firefox
    • Zilla (无头模式)
  6. 实战示例
  7. 最佳实践与注意事项
  8. 官方资源

安装与环境配置

你需要安装 Splinter 库。

pip install splinter

重要: Splinter 本身只是一个“胶水”库,它需要具体的浏览器驱动程序来与浏览器通信,你需要根据你选择的浏览器下载对应的驱动。

以 Chrome 为例

  1. 确保你已安装 Chrome 浏览器。
  2. 下载 ChromeDriver:
    • 访问 Chrome for Testing availability
    • 下载与你 Chrome 浏览器版本匹配的 chromedriver,版本号不匹配是导致最常见的错误之一。
    • 将下载的 chromedriver (或 chromedriver.exe) 文件放在一个系统路径下(如 /usr/local/bin),或者将其路径保存在环境变量中,或者在你的代码中指定其路径。

以 Firefox 为例

  1. 确保你已安装 Firefox 浏览器。
  2. 下载 geckodriver:
    • 访问 Mozilla GeckoDriver Releases
    • 下载与你操作系统匹配的 geckodriver
    • 同样,将其放置在系统路径或指定路径。

核心概念

Driver (浏览器驱动)

Driver 是 Splinter 与实际浏览器(如 Chrome, Firefox)通信的桥梁,不同的浏览器对应不同的 Driver,Splinter 通过 visit() 等方法向 Driver 发送指令,Driver 再将这些指令翻译成浏览器可以理解的操作。

Browser (浏览器实例)

Browser 是你通过 splinter.Browser() 创建的对象,它是你与网页交互的主要入口,创建 Browser 实例时,你需要指定要使用的 Driver

Python Splinter 文档怎么快速上手?-图2
(图片来源网络,侵删)
from splinter import Browser
# 使用 Chrome 浏览器
browser = Browser('chrome')
# 使用 Firefox 浏览器
# browser = Browser('firefox')
# 使用无头模式的 Chrome (需要下载对应版本的 chromedriver)
# browser = Browser('chrome', headless=True)

基本操作

打开与关闭浏览器

from splinter import Browser
# 打开一个浏览器实例
browser = Browser('chrome')
# ... 执行自动化任务 ...
# 关闭浏览器
browser.quit()

注意: browser.quit() 会完全关闭浏览器进程。browser.close() 只会关闭当前标签页,如果还有其他标签页,浏览器进程会继续运行,通常推荐使用 quit()

导航

# 访问一个 URL
browser.visit("https://www.google.com")
# 获取当前页面的 URL
current_url = browser.url
print(f"当前 URL: {current_url}")
# 获取当前页面的标题= browser.title
print(f"页面标题: {page_title}")

与页面交互

点击元素

browser.visit("https://www.example.com")
# 通过 CSS 选择器找到链接并点击
browser.find_by_css('a').click()

输入文本

browser.visit("https://github.com/login")
# 找到用户名输入框
username = browser.find_by_id('login_field')
# 输入文本
username.fill('your_username')

鼠标悬停

Python Splinter 文档怎么快速上手?-图3
(图片来源网络,侵删)
# 假设有一个需要悬停才能显示的下拉菜单
hover_element = browser.find_by_css('.dropdown-toggle')
hover_element.mouse_over()

拖拽

# 假设有两个可拖拽的元素
source = browser.find_by_id('draggable')
target = browser.find_by_id('droppable')
source.drag_and_drop(target)

查找元素

Splinter 提供了多种查找元素的方法,返回的是 ElementList 对象,你可以像操作列表一样操作它。

方法 描述 示例
find_by_id() 通过 ID 查找,唯一 browser.find_by_id('main-content')
find_by_name() 通过 name 属性查找 browser.find_by_name('username')
find_by_tag() 通过 HTML 标签名查找 browser.find_by_tag('h1')
find_by_value() 通过 value 属性查找 browser.find_by_value('submit')
find_by_text() 通过元素的可见文本查找 browser.find_by_text('点击这里')
find_by_css() 通过 CSS 选择器查找(最常用) browser.find_by_css('.container p a')
find_by_xpath() 通过 XPath 查找 browser.find_by_xpath('//div[@id="header"]/a')

获取元素属性或文本

element = browser.find_by_css('h1').first
# 获取元素的文本内容
text = element.text
print(text)
# 获取元素的某个属性
href = element['href']
print(href)
# 判断元素是否可见
is_visible = element.visible
print(is_visible)

处理多个元素

# 找到所有 class 为 'item' 的 div
items = browser.find_by_css('.item')
# 遍历所有元素
for item in items:
    print(item.text)
# 获取第一个元素
first_item = items.first
print(f"第一个元素: {first_item.text}")
# 获取最后一个元素
last_item = items.last
print(f"最后一个元素: {last_item.text}")
# 获取指定索引的元素
second_item = items[1]
print(f"第二个元素: {second_item.text}")

处理表单

browser.visit("https://httpbin.org/forms/post")
# 套餐选择
browser.choose('customer', 'premium') # radio button
# 兴趣选择
browser.check('topping') # checkbox
browser.check('delivery') # checkbox
# 文本输入
browser.fill('custname', 'John Doe')
browser.fill('custtel', '123-456-7890')
browser.fill('size', 'large')
browser.fill('comments', 'This is an automated test.')
# 提交表单
# 通常可以通过找到提交按钮并点击,或者直接调用 forms[0].submit()
browser.find_by_css('button[type="submit"]').click()

执行 JavaScript

# 执行一段简单的 JS 代码
browser.execute_script("alert('Hello from Splinter!');")
# 执行 JS 并获取返回值
# 获取页面上所有链接的数量
link_count = browser.execute_script("return document.links.length;")
print(f"页面上的链接数量: {link_count}")

处理弹窗和警告

browser.is_text_present() 是一个非常强大的工具,可以用来判断弹窗或警告框的出现。

# 点击一个会触发 alert 的按钮
browser.find_by_css('#alert-button').click()
# 等待 alert 出现并获取其文本
# 注意:直接获取 alert 文本在某些驱动中可能不稳定
# 更稳健的方式是判断页面文本
if browser.is_text_present('This is an alert!'):
    print("Alert 弹窗文本已确认。")
# 确认 (Accept) 或取消 (Dismiss) alert
# 这需要根据具体驱动和场景调整
# 对于 ChromeDriver,可能需要使用 `with browser.get_alert() as alert:`
# alert.accept()

页面截图

browser.visit("https://www.example.com")
# 保存截图
browser.save_screenshot('example_screenshot.png')

高级功能

等待元素

现代网页大量使用 AJAX,元素不会立即加载,Splinter 提供了 wait_for_condition 方法来等待某个条件满足。

from splinter import Browser
from splinter.waiting import wait_for_condition
browser = Browser('chrome')
browser.visit("https://example.com/ajax-page")
# 定义一个等待条件
def element_is_loaded(browser):
    return browser.find_by_id('dynamic-element').visible
# 等待最多10秒,直到元素可见
try:
    wait_for_condition(element_is_loaded, timeout=10)
    print("动态元素已加载!")
    print(browser.find_by_id('dynamic-element').text)
except Exception as e:
    print(f"等待超时: {e}")
browser.quit()

注意: wait_for_condition 是一个更底层的等待方式,对于简单的元素出现,find_by_* 方法本身也带有一定的内置等待机制,但 wait_for_condition 更灵活。

文件上传

browser.visit("https://the-internet.herokuapp.com/upload")
# 找到文件输入框
file_upload = browser.find_by_name('file')
# 通过 `attach_file` 方法上传文件
# 你可以提供文件名,它会自动查找项目中的文件
file_upload.attach_file('my_test_file.txt')
# 点击上传按钮
browser.find_by_css('button[type="submit"]').click()

Cookies 处理

browser.visit("https://httpbin.org/cookies")
# 添加一个 Cookie
browser.cookies.add({'name': 'test_cookie', 'value': '12345'})
# 刷新页面以查看 Cookie
browser.reload()
# 获取所有 Cookies
all_cookies = browser.cookies.all()
print(f"所有 Cookies: {all_cookies}")
# 删除指定的 Cookie
browser.cookies.delete('test_cookie')
# 删除所有 Cookies
browser.cookies.delete()

常用 Driver 介绍

ChromeDriver

  • 特点: 市场份额最大,功能最丰富,调试方便(因为有可视化界面)。
  • 用法: Browser('chrome')
  • 无头模式: Browser('chrome', headless=True),在服务器或 CI/CD 环境中非常有用。

Firefox

  • 特点: 开源,社区支持好,对 Web 标准支持良好。
  • 用法: Browser('firefox')
  • 无头模式: Browser('firefox', headless=True)

Zilla (推荐的无头选择)

注意: Zilla 是一个基于 Chrome 的无头浏览器,但比 ChromeDriver 的无头模式更稳定、更符合 W3C 标准,并且更容易配置。对于生产环境和无头自动化,强烈推荐使用 Zilla

  • 特点: 基于 Chromium,无头模式,性能好,配置简单。
  • 安装: pip install zilla
  • 用法: Browser('zilla')
  • 无头模式: Browser('zilla', headless=True) 是默认行为,无需额外配置。

实战示例:登录 GitHub 并获取仓库列表

from splinter import Browser
import time
# 使用 Zilla 浏览器,无头模式
browser = Browser('zilla')
try:
    # 1. 访问 GitHub 登录页面
    print("正在访问 GitHub 登录页面...")
    browser.visit("https://github.com/login")
    # 2. 填写用户名和密码
    print("正在填写登录信息...")
    browser.fill("login", "YOUR_GITHUB_USERNAME")
    browser.fill("password", "YOUR_GITHUB_PASSWORD")
    # 3. 点击登录按钮
    print("正在点击登录按钮...")
    browser.find_by_name("commit").click()
    # 4. 等待页面跳转,并检查是否登录成功
    # 这里简单等待5秒,实际项目中应使用 wait_for_condition
    print("等待页面加载...")
    time.sleep(5) 
    # 检查页面是否包含 "Repositories" 文本
    if browser.is_text_present("Repositories"):
        print("登录成功!")
        # 5. 访问仓库页面
        print("正在访问仓库页面...")
        browser.visit("https://github.com/YOUR_GITHUB_USERNAME?tab=repositories")
        # 6. 获取所有仓库的名称
        print("正在获取仓库列表...")
        repo_elements = browser.find_by_css('div[role="row"] h3 a')
        print("你的仓库列表:")
        for repo in repo_elements:
            print(f"- {repo.text}")
    else:
        print("登录失败,请检查用户名和密码。")
except Exception as e:
    print(f"发生错误: {e}")
finally:
    # 7. 无论成功与否,都关闭浏览器
    print("正在关闭浏览器...")
    browser.quit()

最佳实践与注意事项

  1. 使用无头模式进行自动化: 在服务器或持续集成环境中,务必使用无头模式(如 Zillachrome + headless=True)来提高效率。
  2. 显式等待优于隐式等待: 避免使用 time.sleep(),它既不精确又会降低脚本效率,优先使用 wait_for_condition 或利用 find_by_* 方法的内置智能等待。
  3. 使用可靠的定位器: ID 是最稳定的选择,其次是 CSS 选择器,尽量避免使用复杂的 XPath,除非必要。
  4. 使用 try...finallywith 语句: 确保浏览器在任何情况下都能被正确关闭,避免资源泄露。
  5. 处理动态内容: 对于由 JavaScript 动态加载的内容,一定要有等待机制,确保脚本在元素加载完成后再进行操作。
  6. 错误处理: 网络不稳定、页面结构变化等都可能导致脚本失败,使用 try...except 块来捕获和处理这些异常,使脚本更健壮。

官方资源

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