首页 > 后端开发 > Python教程 > 使用 Selenium 和 Python 构建强大的 Web 自动化

使用 Selenium 和 Python 构建强大的 Web 自动化

DDD
发布: 2025-01-07 00:04:43
原创
671 人浏览过

网络自动化现在是现代软件开发和测试中不可或缺的工具。在这个全面的 Selenium Python 教程中,您将学习如何构建一个能够处理现实场景的强大的 Web 自动化框架。如果您有兴趣在 Python 中实现自动化测试或创建复杂的网页抓取自动化解决方案,本指南将为您提供经过行业测试的方法和 Selenium 最佳实践。

了解 Web 自动化基础知识

网络自动化对于现代软件开发、测试和数据收集至关重要。其应用程序涵盖从 Web 应用程序的端到端测试到简化重复的工作流程,例如表单提交或网页抓取。虽然 Selenium WebDriver Python 集成提供了强大的功能,但强大的 Web 自动化不仅仅是编写脚本来模拟用户交互。它涉及设计可维护、适应性强且能够适应目标 Web 应用程序更改的工作流程和框架。

以下是我们将在本教程中介绍的关键方面:

  • 选择适当的定位器(XPath、CSS 等)
  • 动态元素和状态加载
  • 实施重试机制
  • 正确管理浏览器会话
  • 代码的可维护性结构

我们将使用 Books to Scrape 作为演示网站,为电子商务网站上的价格跟踪器构建一个网络抓取自动化项目,以演示这些概念,同时遵循 Selenium 最佳实践。

先决条件

要学习本教程,您需要:

  • Python 3.x 安装在您的计算机上。
  • Python编程基础知识
  • 使用 Selenium 进行网页抓取的基础知识

本教程的代码可在我们的 github 存储库中找到,请随意克隆它以继续学习。

设置开发环境

让我们设置一个合适的开发环境并安装必要的Python包。首先,通过运行以下命令创建项目文件夹和新的虚拟环境:

mkdir price_tracker_automation && cd price_tracker_automation
python3 -m venv env
source env/bin/activate
登录后复制
登录后复制
登录后复制
登录后复制

然后,创建以下 Python 包并将其添加到您的requirements.txt 文件中:

selenium==4.16.0
webdriver-manager==4.0.1
python-dotenv==1.0.0
requests==2.31.0
登录后复制
登录后复制
登录后复制
登录后复制

在上面的代码中,我们定义了核心依赖项。 selenium 包为我们的 Web 自动化框架提供了基础,而 webdriver-manager 自动处理浏览器驱动程序管理。 python-dotenv 包用于环境配置,requests 包用于 HTTP 请求处理。

现在运行以下命令来安装您的requirements.txt 文件中的所有Python 包:

pip install -r requirements.txt
登录后复制
登录后复制
登录后复制
登录后复制

最后,为我们的项目创建以下文件夹结构:

mkdir price_tracker_automation && cd price_tracker_automation
python3 -m venv env
source env/bin/activate
登录后复制
登录后复制
登录后复制
登录后复制

在这里,我们遵循软件工程最佳实践建立了模块化项目结构。 core 目录包含我们的主要自动化组件,而 database 处理数据持久性。

构建价格跟踪工具

创建了项目环境、依赖项和文件夹结构后,让我们继续使用 Selenium 和 Python 构建价格跟踪器自动化工具。

实施我们的浏览器管理系统

让我们实现我们的浏览器管理系统,这是稳定的 Selenium WebDriver Python 集成的重要组件。将下面的代码片段添加到您的 core/browser.py 文件中:

selenium==4.16.0
webdriver-manager==4.0.1
python-dotenv==1.0.0
requests==2.31.0
登录后复制
登录后复制
登录后复制
登录后复制

上面的代码创建了一个 BrowserManager 类来处理 WebDriver 的初始化和配置。该课程通过配置 Chrome 选项来实现稳定性和性能,从而实现 Selenium 最佳实践。 headless 参数允许在没有可见浏览器窗口的情况下运行测试,这对于 CI/CD 管道至关重要。

现在将以下方法添加到 BrowserManager 类中以实现核心浏览器管理功能:

pip install -r requirements.txt
登录后复制
登录后复制
登录后复制
登录后复制

在上面的代码中,start_browser 方法利用 webdriver-manager 自动处理驱动程序安装和更新,而 close_browser 则确保正确的资源清理。该实现包括隐式等待配置,以优雅地处理动态页面加载。

创建元素处理程序

接下来,让我们继续实现元素交互系统,这在任何 Web 自动化框架中都很重要,因为它使我们能够以可靠的方式检测元素并与元素交互,同时遵循 Selenium 的最佳实践。将代码片段添加到您的 core/element_handler.py

price_tracker_automation/
├── core/
│   ├── browser.py
|   ├── scraper.py
│   └── element_handler.py
├── database/
│   └── db_manager.py
├── notifications/
|   └── price_alert.py
├── requirements.txt
├── run.py
└── main.py
登录后复制
登录后复制
登录后复制

在上面的代码中,我们创建了一个 ElementHandler 类,它封装了 Selenium WebDriver Python 交互模式。该类接受 WebDriver 实例和可配置的超时参数。

更新您的 ElementHandler 类以添加核心元素交互方法:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support import expected_conditions as EC
import logging

class BrowserManager:
    def __init__(self, headless=False):
        self.options = webdriver.ChromeOptions()
        if headless:
            self.options.add_argument('--headless')

        # Add additional stability options
        self.options.add_argument('--no-sandbox')
        self.options.add_argument('--disable-dev-shm-usage')
        self.options.add_argument('--disable-gpu')

        self.driver = None
        self.logger = logging.getLogger(__name__)
登录后复制
登录后复制

上述方法使用Selenium的WebDriverWait和expected_conditions来检测元素,以便它也可以处理元素可能异步加载的动态网页。

添加另一种方法来实现文本提取逻辑:

    def start_browser(self):
        """Initialize and return a ChromeDriver instance"""
        try:
 service = webdriver.ChromeService()
            self.driver = webdriver.Chrome(service=service, options=self.options)
            self.driver.implicitly_wait(10)
            return self.driver
        except Exception as e:
            self.logger.error(f"Failed to start browser: {str(e)}")
            raise

    def close_browser(self):
        """Safely close the browser"""
        if self.driver:
            self.driver.quit()
            self.driver = None
登录后复制
登录后复制

该方法包含重试逻辑来处理 StaleElementReferenceException,这是 Web 自动化中的常见挑战。

实施价格跟踪器核心

现在让我们构建主要的抓取功能,结合自动化测试 Python 概念和强大的错误处理。将下面的代码片段添加到您的 core/scraper.py 文件中:

mkdir price_tracker_automation && cd price_tracker_automation
python3 -m venv env
source env/bin/activate
登录后复制
登录后复制
登录后复制
登录后复制

在上面的代码中,我们创建了 BookScraper 类,它集成了浏览器和元素处理组件。该类遵循页面对象模型模式,这是 Web 自动化框架设计中的一个关键概念,通过集中元素定位器并为抓取操作提供干净的 API。

接下来,更新BookScraper类以添加核心产品数据提取方法:

selenium==4.16.0
webdriver-manager==4.0.1
python-dotenv==1.0.0
requests==2.31.0
登录后复制
登录后复制
登录后复制
登录后复制

上述方法使用结构化方法来收集产品信息,维护详细日志以进行调试和监控。

设置数据库管理

让我们实现 Web 自动化框架的数据库层,它将处理我们抓取的数据的持久存储。该组件将使我们能够跟踪价格随时间的变化。将以下代码片段添加到您的database/db_manager.py:

pip install -r requirements.txt
登录后复制
登录后复制
登录后复制
登录后复制

在上面的代码中,我们定义了处理所有数据库操作的 DatabaseManager 类。我们使用 SQLite 是为了简单性和可移植性,以避免设置和配置数据库,而且 SQLite 也是我们的网络抓取自动化项目的理想选择,因为我们不存储大量数据。

接下来,更新你的database/db_manager.py以添加数据库初始化方法:

price_tracker_automation/
├── core/
│   ├── browser.py
|   ├── scraper.py
│   └── element_handler.py
├── database/
│   └── db_manager.py
├── notifications/
|   └── price_alert.py
├── requirements.txt
├── run.py
└── main.py
登录后复制
登录后复制
登录后复制

在这里,我们使用 SQL DDL 语句建立数据库模式,并为产品和价格历史创建单独的表,并具有适当的关系和约束,这将使我们能够跟踪价格并对我们存储的数据执行历史分析。

现在让我们添加另一种方法来将数据保存到数据库:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support import expected_conditions as EC
import logging

class BrowserManager:
    def __init__(self, headless=False):
        self.options = webdriver.ChromeOptions()
        if headless:
            self.options.add_argument('--headless')

        # Add additional stability options
        self.options.add_argument('--no-sandbox')
        self.options.add_argument('--disable-dev-shm-usage')
        self.options.add_argument('--disable-gpu')

        self.driver = None
        self.logger = logging.getLogger(__name__)
登录后复制
登录后复制

在上面的代码中,我们使用参数化查询实现了数据持久化逻辑,以防止SQL注入。该方法使用 SQLite 的 ON CONFLICT 子句处理插入和更新操作。

主要应用集成

让我们将所有内容与我们的主应用程序类联系在一起,合并 Selenium WebDriver Python 实现的所有元素。将以下代码片段添加到您的 main.py 文件中:

    def start_browser(self):
        """Initialize and return a ChromeDriver instance"""
        try:
 service = webdriver.ChromeService()
            self.driver = webdriver.Chrome(service=service, options=self.options)
            self.driver.implicitly_wait(10)
            return self.driver
        except Exception as e:
            self.logger.error(f"Failed to start browser: {str(e)}")
            raise

    def close_browser(self):
        """Safely close the browser"""
        if self.driver:
            self.driver.quit()
            self.driver = None
登录后复制
登录后复制

在上面的代码中,我们创建了主要的 PriceTracker 类,该类协调我们的网络抓取自动化解决方案的所有组件。 PriceTracker 类遵循依赖注入模式来保持模块化和可测试性。

接下来,更新我们的 PriceTracker 类以添加核心跟踪方法:

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, StaleElementReferenceException

class ElementHandler:
    def __init__(self, driver, timeout=10):
        self.driver = driver
        self.timeout = timeout
登录后复制

在这里,我们实现了主要的产品跟踪逻辑,用于处理网络抓取并存储抓取的数据。

运行应用程序

让我们创建一个执行脚本来运行我们的自动化脚本。将以下代码片段添加到您的 run.py 文件中:

   def wait_for_element(self, locator, timeout=None):
        """Wait for element with retry mechanism"""
 timeout = timeout or self.timeout
        try:
 element = WebDriverWait(self.driver, timeout).until(
 EC.presence_of_element_located(locator)
 )
            return element
        except TimeoutException:
            raise TimeoutException(f"Element {locator} not found after {timeout} seconds")

    def get_text_safely(self, locator, timeout=None):
        """Safely get text from element with retry mechanism"""
 max_retries = 3
        for attempt in range(max_retries):
            try:
 element = self.wait_for_element(locator, timeout)
                return element.text.strip()
            except StaleElementReferenceException:
                if attempt == max_retries - 1:
                    raise
                continue
登录后复制

现在在终端上运行以下命令来运行脚本:

mkdir price_tracker_automation && cd price_tracker_automation
python3 -m venv env
source env/bin/activate
登录后复制
登录后复制
登录后复制
登录后复制

上面的命令将在下面的屏幕截图中显示输出:

Building Robust Web Automation with Selenium and Python

从上面的脚本中,您可以看到我们的自动化脚本正在跟踪所有指定 URL 的价格。

追踪价格变化

我们当前的实施仅跟踪和保存产品价格。跟踪价格后,让我们增强我们的价格跟踪器以通知用户价格变化。将以下代码片段添加到您的 notification/price_alert.py 文件中:

selenium==4.16.0
webdriver-manager==4.0.1
python-dotenv==1.0.0
requests==2.31.0
登录后复制
登录后复制
登录后复制
登录后复制

在上面的代码片段中,我们创建了一个具有基本依赖项的 PriceAlertManager 类。管理器将数据库管理器实例作为参数,并设置日志记录以跟踪警报操作。该类使用复杂的连接来比较当前和以前的价格。然后我们实现了动态价格变化百分比计算,并为价格变化信息创建了一个结构化字典。

接下来,更新您的 PriceAlertManager 类以添加电子邮件通知功能:

pip install -r requirements.txt
登录后复制
登录后复制
登录后复制
登录后复制

在这里,我们使用 Python 的电子邮件和 SMTP 库创建了电子邮件通知。该实现使用 MIMEText 类来创建格式正确的电子邮件。电子邮件正文是使用 f 字符串动态生成的,包含详细的价格变化信息和精确的货币格式。

现在让我们修改运行脚本以包含价格警报:

price_tracker_automation/
├── core/
│   ├── browser.py
|   ├── scraper.py
│   └── element_handler.py
├── database/
│   └── db_manager.py
├── notifications/
|   └── price_alert.py
├── requirements.txt
├── run.py
└── main.py
登录后复制
登录后复制
登录后复制

现在,如果您再次运行该脚本,它将跟踪产品价格并提醒您价格发生变化的产品,如下面的屏幕截图所示:

Building Robust Web Automation with Selenium and Python

也许您可以在 cron 作业中运行此脚本来跟踪产品价格并实时提醒您价格变化,而无需每次都手动运行它。
例如。 0 */6 * * * python run.py --urls
“http://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html”
“http://books.toscrape.com/catalogue/tipping-the-velvet_999/index.html”
“http://books.toscrape.com/catalogue/soumission_998/index.html”

结论

通过本教程,您学习了如何使用 Selenium 和 Python 构建强大的 Web 自动化工具。我们首先了解网络自动化基础知识,然后为我们为本教程中的演示构建的 Price Traker 工具建立一个开发环境。然后,我们进一步构建了价格跟踪应用程序,用于跟踪产品价格并提醒用户价格变化。现在您已经掌握了这些知识,接下来您将构建什么工具。请在评论部分告诉我。快乐编码!

以上是使用 Selenium 和 Python 构建强大的 Web 自动化的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板