杰瑞科技汇

Selenium Python如何操作数据库?

Selenium Python如何操作数据库?-图1
(图片来源网络,侵删)
  1. 使用 Selenium:控制浏览器(如 Chrome, Firefox)打开网页,与页面元素进行交互(点击、输入、滚动等)。
  2. 抓取数据:从网页的 HTML 结构中提取你感兴趣的信息(如商品标题、价格、新闻标题、文章内容等)。
  3. 处理数据:对抓取到的数据进行清洗、格式化,使其符合数据库的存储要求。
  4. 连接数据库:使用 Python 的数据库连接库(如 pymysql 用于 MySQL,psycopg2 用于 PostgreSQL,sqlite3 用于 SQLite)建立与数据库的连接。
  5. 存储数据:将处理好的数据通过 SQL 语句(如 INSERT)插入到数据库的相应表中。

第一步:环境准备

在开始之前,请确保你已经安装了必要的库。

  1. Selenium

    pip install selenium
  2. 浏览器驱动

    • 你需要下载与你浏览器版本匹配的 WebDriver,如果你使用 Chrome 浏览器,你需要下载 ChromeDriver
    • 重要:确保 WebDriver 的版本与你的 Chrome 浏览器版本大致匹配。
    • 将下载好的 chromedriver.exe (Windows) 或 chromedriver (macOS/Linux) 放在你的项目目录下,或者将其路径添加到系统的环境变量 PATH 中。
  3. 数据库连接库

    Selenium Python如何操作数据库?-图2
    (图片来源网络,侵删)
    • MySQL: pip install pymysql
    • PostgreSQL: pip install psycopg2-binary
    • SQLite: Python 内置,无需额外安装。

第二步:一个完整的示例(抓取书籍信息并存入 SQLite)

我们将抓取一个假设的图书列表网站,并将书名和价格存入 SQLite 数据库。

目标网站分析

假设我们有一个简单的 HTML 页面,结构如下:

<!DOCTYPE html>
<html>
<head>图书列表</title>
</head>
<body>
    <h1>我的书架</h1>
    <div class="book-list">
        <div class="book-item">
            <h2 class="title">Python编程:从入门到实践</h2>
            <p class="price">¥89.00</p>
        </div>
        <div class="book-item">
            <h2 class="title">流畅的Python</h2>
            <p class="price">¥129.00</p>
        </div>
        <div class="book-item">
            <h2 class="title"> Selenium自动化测试:基于Python</h2>
            <p class="price">¥79.00</p>
        </div>
    </div>
</body>
</html>

Python 代码实现

import time
import sqlite3
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
# --- 1. Selenium 设置 ---
# 设置 Chrome 选项 (例如无头模式)
chrome_options = Options()
# chrome_options.add_argument("--headless") # 无头模式,不显示浏览器窗口
chrome_options.add_argument("--disable-gpu")
# 指定 ChromeDriver 路径 (如果不在 PATH 中)
# service = Service(executable_path='path/to/your/chromedriver')
# driver = webdriver.Chrome(service=service, options=chrome_options)
# chromedriver 在 PATH 中,可以直接这样初始化
driver = webdriver.Chrome(options=chrome_options)
# --- 2. 数据库设置 ---
# 创建一个内存中的 SQLite 数据库 (如果需要持久化,将 ':memory:' 替换为文件名,如 'books.db')
conn = sqlite3.connect(':memory:')
cursor = conn.cursor()
# 创建一个表来存储书籍信息
create_table_query = """
CREATE TABLE IF NOT EXISTS books (
    id INTEGER PRIMARY KEY AUTOINCREMENT,TEXT NOT NULL,
    price TEXT NOT NULL
)
"""
cursor.execute(create_table_query)
print("数据库表 'books' 创建成功。")
# --- 3. 抓取数据 ---
try:
    # 打开目标网页 (这里我们用一个本地HTML文件作为示例)
    # 在实际应用中,这里应该是真实的URL,如 driver.get("https://www.example.com/books")
    driver.get("file:///path/to/your/local_books.html") # !!! 请替换为你的本地HTML文件路径
    # 等待页面加载
    time.sleep(2)
    # 定位所有的书籍元素
    book_elements = driver.find_elements(By.CLASS_NAME, "book-item")
    print(f"找到 {len(book_elements)} 本书。")
    # 遍历每个书籍元素
    for book in book_elements:
        # 提取书名和价格
        title_element = book.find_element(By.CLASS_NAME, "title")
        price_element = book.find_element(By.CLASS_NAME, "price")
        title = title_element.text
        price = price_element.text
        print(f"抓取到: 书名='{title}', 价格='{price}'")
        # --- 4. 将数据存入数据库 ---
        # 使用参数化查询来防止 SQL 注入
        insert_query = "INSERT INTO books (title, price) VALUES (?, ?)"
        cursor.execute(insert_query, (title, price))
    # 提交事务
    conn.commit()
    print(f"成功将 {cursor.rowcount} 条数据插入数据库。")
    # --- 5. 验证数据 ---
    print("\n--- 数据库中的内容 ---")
    cursor.execute("SELECT * FROM books")
    rows = cursor.fetchall()
    for row in rows:
        print(row)
except Exception as e:
    print(f"发生错误: {e}")
    # 如果出错,回滚事务
    conn.rollback()
finally:
    # --- 6. 关闭连接 ---
    # 关闭浏览器
    driver.quit()
    # 关闭数据库连接
    conn.close()
    print("浏览器和数据库连接已关闭。")

关键点详解

Selenium 部分

  • webdriver.Chrome(): 初始化一个 Chrome 浏览器实例。
  • driver.get(url): 导航到指定的 URL。
  • 定位元素:
    • find_elements(): 返回一个元素列表,用于获取多个匹配项(如所有书籍)。
    • find_element(): 返回单个元素。
    • By.CLASS_NAME, By.ID, By.XPATH, By.CSS_SELECTOR 等是常用的定位策略,XPath 和 CSS Selector 通常更强大和灵活。
  • element.text: 获取元素的可见文本内容。

数据库部分 (以 SQLite 为例)

  • sqlite3.connect(): 建立与数据库文件的连接。':memory:' 表示创建一个临时的内存数据库,程序关闭后数据即丢失。
  • conn.cursor(): 创建一个游标对象,所有 SQL 操作都通过这个游标执行。
  • CREATE TABLE IF NOT EXISTS: 这是一个好习惯,可以防止脚本因表已存在而报错。
  • cursor.execute(sql, params): 执行 SQL 语句。
    • 参数化查询: VALUES (?, ?) 是参数占位符。(title, price) 是一个元组,包含了要替换占位符的实际值。这至关重要! 它可以防止 SQL 注入攻击,并使代码更清晰。
  • conn.commit(): 将事务中的所有更改保存到数据库,在 INSERT, UPDATE, DELETE 操作后必须调用。
  • conn.rollback(): 如果在事务中发生错误,调用此方法可以撤销所有未提交的更改。
  • conn.close(): 关闭数据库连接,释放资源。

进阶:处理分页网站

对于有分页的网站,你需要模拟点击“下一页”按钮,并重复抓取和存储的过程。

# ... (前面的数据库和Selenium设置代码相同)
next_button_exists = True
page_num = 1
while next_button_exists:
    print(f"--- 正在抓取第 {page_num} 页 ---")
    # 1. 抓取当前页数据
    # ... (你的抓取逻辑) ...
    # 2. 存储到数据库
    # ... (你的存储逻辑) ...
    # 3. 尝试点击“下一页”按钮
    try:
        # 根据实际情况定位“下一页”按钮
        next_button = driver.find_element(By.XPATH, "//a[contains(text(), '下一页')]")
        next_button.click()
        time.sleep(3) # 等待新页面加载
        page_num += 1
    except:
        print("找不到“下一页”按钮,或已是最后一页。")
        next_button_exists = False
# ... (后面的提交和关闭代码) ...

进阶:处理动态加载内容

很多现代网站使用 AJAX 或 JavaScript 动态加载数据,直接 find_element() 可能会失败,因为元素还不存在。

Selenium Python如何操作数据库?-图3
(图片来源网络,侵删)

解决方案:显式等待

显式等待会告诉 Selenium 在执行下一步之前,等待某个条件(如元素可见、可点击)成立,或者超时。

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# ...
try:
    # 等待最多10秒,直到ID为"dynamic-content"的元素变得可见
    element = WebDriverWait(driver, 10).until(
        EC.visibility_of_element_located((By.ID, "dynamic-content"))
    )
    # 元素可见后,再进行操作
    print(element.text)
except TimeoutException:
    print("在指定时间内未找到元素。")
# ...

将 Selenium、Python 和数据库结合使用,可以实现强大的数据抓取和自动化测试流程,核心在于:

  1. Selenium 负责“看”和“动”:与浏览器交互,获取网页内容。
  2. Python 负责“想”和“做”:逻辑控制、数据清洗、与数据库通信。
  3. 数据库 负责“记”:持久化存储抓取到的结构化数据。

记住始终使用参数化查询来操作数据库,这是保证安全性的基本要求,合理使用显式等待来处理动态加载的网页,可以使你的脚本更加健壮。

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