You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Selenium/PyAutoGUI自动化保存动态网页为XHT文件遇阻求助

问题描述

我是一名教师,需要批量下载课程所需电子书页面用于离线查看,目前遇到以下问题:

  • 用Selenium搭配PyAutoGUI/Keys模拟Ctrl+S保存XHT文件,手动操作可行但自动化无响应,浏览器加载页面后不执行按键操作
  • 直接爬取XHTML页面仅能拿到空结构,网页为动态生成;用Insomnia发送GET请求能正常显示内容,但Python复现请求后内容仍为空,下载Insomnia接收的文件也只有空结构
  • 仅手动通过浏览器「文件-另存为」保存完整XHT文件能满足需求,需要将此流程自动化并整合到现有爬虫程序中,要求保留文本可编辑性,不能采用截图或PDF打印方式

当前代码

import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import pyautogui

# List of URLs for each page of the ebook
page_urls = [
    'https://ebooks.boost-learning.co.uk/4Pim8vo0ePBcsNbNvor5qBJlswtEnDHR/FNovrUipJO_ex-bo/9781398372870-1.1.1/EPUB/fxl/page008.xhtml',
    # Add more page URLs here
]

# Initialize the webdriver
driver = webdriver.Chrome()

# Loop through each page URL
for url in page_urls:
    # Open the URL in the webdriver
    driver.get(url)

    # Wait for the page to load
    time.sleep(5)

    # Press the Ctrl+S keyboard shortcut to save the page
    pyautogui.press('ctrl+s')

    # Wait for the save dialog to appear
    time.sleep(5)

    # Press the Enter key to save the page
    pyautogui.press('enter')

# Close the webdriver
driver.quit()
解决方案

针对上述问题,提供几个实用的优化方向:

1. 修复模拟按键无响应问题

  • 确保浏览器窗口处于前台:PyAutoGUI的按键操作依赖当前活跃窗口,触发保存前先激活浏览器:
    driver.maximize_window()
    # 点击浏览器内容区域激活窗口
    pyautogui.click(driver.find_element(By.TAG_NAME, 'body').location)
    
  • 替换固定等待为显式等待:用WebDriverWait等待页面关键元素加载完成,比time.sleep()更可靠:
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.common.by import By
    
    # 替换原time.sleep(5)
    WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.TAG_NAME, "body"))
    )
    
  • 优化组合键触发方式:改用pyautogui.hotkey('ctrl', 's')替代press,模拟组合键的连贯性更好;Mac系统替换为hotkey('command', 's')

2. 直接获取渲染后的页面源码

如果手动保存能拿到完整内容,说明页面已完成JS渲染,可直接提取Selenium驱动中的页面源码写入文件,无需模拟保存对话框:

for idx, url in enumerate(page_urls):
    driver.get(url)
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.TAG_NAME, "body")))
    # 提取渲染后的源码并保存
    filename = f"page{idx+1:03d}.xht"
    with open(filename, 'w', encoding='utf-8') as f:
        f.write(driver.page_source)

3. 用CDP命令实现稳定保存

如果必须使用浏览器原生的「另存为」功能,可通过Chrome DevTools Protocol(CDP)直接调用浏览器API,绕过系统对话框,稳定性更高:

for idx, url in enumerate(page_urls):
    driver.get(url)
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.TAG_NAME, "body")))
    # 调用CDP命令保存页面
    driver.execute_cdp_cmd("Page.saveAs", {
        "url": url,
        "suggestedFilename": f"page{idx+1:03d}.xht"
    })

内容的提问来源于stack exchange,提问作者Rijff Swanepoel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 09:20:21