如何使用Python Selenium截取网页指定考试题目元素的局部截图
Selenium题库元素截图及内容提取解决方案
常见screenshot_as_png调用失败原因
- 元素未完成加载就执行截图操作,没有做可见性等待
- Selenium版本低于4.0,旧版本对超出屏幕的长元素截图支持存在缺陷
- 目标元素被页面固定导航栏、浮动广告、弹窗等元素遮挡,导致截图区域被覆盖
方案1:精准截取单个题目元素(支持超出屏幕的长内容)
Selenium 4+ 版本原生支持单个元素完整截图,即使元素高度超出当前屏幕显示范围也可自动完整截取,代码示例如下:
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By # 1. 显式等待目标题目div加载完成,替换为你自己的元素定位规则 wait = WebDriverWait(driver, 10) question_selector = "替换为你定位题目div的CSS选择器/XPath" question_div = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, question_selector))) # 2. 滚动到元素顶部,避免被顶部固定导航遮挡,关闭滚动动画避免延迟 driver.execute_script("arguments[0].scrollIntoView({block: 'start', behavior: 'instant'});", question_div) # 可选:如果有浮动遮挡元素,可执行JS隐藏,示例隐藏class为fixed-nav的导航栏 # driver.execute_script("document.querySelector('.fixed-nav').style.display = 'none';") # 3. 直接截取元素完整内容,保存到本地 with open("第1题截图.png", "wb") as f: f.write(question_div.screenshot_as_png)
如果还是存在截不全的情况,可以在Chrome启动时调整窗口参数,拉高窗口高度:
from selenium import webdriver options = webdriver.ChromeOptions() options.add_argument("--window-size=1920,5000") # 按需调整高度值,足够容纳最长题目即可 options.add_argument("--start-maximized") driver = webdriver.Chrome(options=options)
方案2:提取带图片的完整题目内容(替代方案)
如果截图方案不符合需求,可以直接导出题目元素的完整HTML并下载关联图片,实现离线保存完整题目内容,代码示例如下:
import os import requests # 1. 创建本地存储目录 save_dir = "./第1题资料" os.makedirs(save_dir, exist_ok=True) # 2. 获取题目元素完整HTML代码 question_html = question_div.get_attribute("outerHTML") # 3. 提取题目内所有图片,下载到本地并替换HTML内的图片路径 img_tags = question_div.find_elements(By.TAG_NAME, "img") for idx, img in enumerate(img_tags): img_url = img.get_attribute("src") if not img_url: continue # 下载图片,按需添加headers避免反爬拦截 headers = { "User-Agent": driver.execute_script("return navigator.userAgent;") } img_data = requests.get(img_url, headers=headers).content img_save_name = f"img_{idx}.png" with open(os.path.join(save_dir, img_save_name), "wb") as f: f.write(img_data) # 替换HTML内的网络图片路径为本地路径 question_html = question_html.replace(img_url, img_save_name) # 4. 保存为本地HTML文件,打开即可查看带格式、带图片的完整题目 with open(os.path.join(save_dir, "题目内容.html"), "w", encoding="utf-8") as f: f.write(f""" <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>题目内容</title> </head> <body style="padding: 20px;"> {question_html} </body> </html> """)
注意事项
- 如果站点有反爬策略,请求图片时要携带和浏览器一致的请求头,避免出现403无权限错误
- 提取内容前确认元素已完全加载,动态渲染的内容可以加延迟等待,或者判断元素内的图片是否全部加载完成
内容的提问来源于stack exchange,提问作者MyDisplay
相关产品推荐
相关产品推荐

