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

Selenium截取LaTeX公式截图时放大后异常问题求助

问题:Selenium截取LaTeX公式截图的分辨率与白屏问题

低缩放比例下,脚本生成的截图正常但公式分辨率不足;高缩放时,手动检查元素保存的截图效果良好,但Selenium生成的截图质量很差,还偶尔出现大块白屏。

脚本说明

需先执行以下命令安装依赖,运行后会在当前目录创建temp文件夹并保存图片:

pip install selenium pyautogui webdriver-manager

原脚本代码

import os
import time

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
# from selenium.webdriver.chrome.options import Options
import pyautogui

dry_run = False  # if False, don't save anything
save_to_temp_folder = True  # if True, save to temp folder instead of content/formulas (for previewing)
# chrome_options = Options()
# chrome_options.add_argument("--headless")
driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()))

driver.get('http://stemformulas.com/formulas')
driver.implicitly_wait(10)

def zoom_in(times=1):
    for i in range(times):
        pyautogui.hotkey('command', '+')

# Find the list items within the specified <ul> element
ul_element = driver.find_element(By.CSS_SELECTOR, 'ul.flex.flex-row.mt-8')
list_items = ul_element.find_elements(By.TAG_NAME, 'li')

# Count the number of list items. Subtract one for the next button.
page_count = len(list_items) - 1
print(f"Found {page_count} pages of formulas")

# increase zoom to 400% for higher quality screenshots
# zoom_in(4)
# driver.execute_script("document.body.style.zoom = '200%'")

for i in range(1, page_count + 1): # iterate over pages
    print("Visiting page: ", i)
    # visit formulas page
    driver.get(f'http://stemformulas.com/formulas/page/{i}')

    # Find the section with class "grid-container mt-6"
    section = driver.find_element(By.CSS_SELECTOR, 'section.grid-container.mt-6')

    # Find all anchor elements within the section
    anchors = section.find_elements(By.TAG_NAME, 'a')
    num_anchors = len(anchors)
    print(f"Found ", num_anchors, " formula grid items")

    # Iterate over the formula grid items
    for i in range(num_anchors):
        # if I iterate over the anchors they become stale so refetch section, anchors every time
        section = driver.find_element(By.CSS_SELECTOR, 'section.grid-container.mt-6')
        anchors = section.find_elements(By.TAG_NAME, 'a')
        anchor = anchors[i]
        href = anchor.get_attribute('href')
        x_path = f"//*[@id=\"main-content\"]/section[2]/a[{i+1}]/div[1]"

        div = anchor.find_element(By.XPATH, x_path)
        div.location_once_scrolled_into_view # scroll into view
        # http://stemformulas.com/formulas/<folder_name>/
        folder_name = href.split('/')[-2]
        output_image_path = os.path.join("content", "formulas", folder_name, "preview.png")
        
        if dry_run:
            print(f"Would have screenshot div {div} to {output_image_path}")
        elif save_to_temp_folder:
            if not os.path.exists("temp"):
                os.mkdir("temp")
            if not os.path.exists(os.path.join("temp", folder_name)):
                os.mkdir(os.path.join("temp", folder_name))
            new_path = os.path.join("temp", folder_name, "preview.png")
            bits = div.screenshot_as_png
            with open(new_path, 'wb') as f:
                f.write(bits)
            print(f"Screenshot div {div} to {new_path}")
            time.sleep(1)
        else:
            bits = div.screenshot_as_png
            with open(output_image_path, 'wb') as f:
                f.write(bits)
            print(f"Screenshot div {div} to {output_image_path}")
            time.sleep(1) # if we don't sleep, elements become stale

已尝试的方案

  • 使用driver.execute_script("document.body.style.zoom = '400%'"),截图效果更差
  • 使用headless模式,未解决问题

解决方案

1. 用Chrome设备像素比参数提升原生分辨率

使用--force-device-scale-factor参数设置全局缩放,这是Chrome原生的缩放方式,比JS修改或模拟快捷键更稳定,直接提升截图分辨率:

from selenium.webdriver.chrome.options import Options

chrome_options = Options()
# 设置4倍设备像素比(对应400%缩放)
chrome_options.add_argument("--force-device-scale-factor=4")
# 若使用headless模式,需配合窗口大小设置
chrome_options.add_argument("--headless=new")
chrome_options.add_argument("--window-size=1920,1080")

driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()), options=chrome_options)

2. 等待LaTeX公式完全渲染

implicitly_wait仅等待元素出现,不等待渲染完成。添加显式等待监听公式渲染状态(以KaTeX为例):

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# 滚动到元素后,等待公式渲染完成
div.location_once_scrolled_into_view
WebDriverWait(driver, 5).until(
    EC.presence_of_element_located((By.CSS_SELECTOR, ".katex"))
)
time.sleep(0.5) # 额外等待确保渲染稳定

3. 优化元素定位避免Stale异常

改用JS直接获取元素,减少重复定位的开销与StaleElement异常:

# 替换原循环内的元素定位逻辑
for idx in range(num_anchors):
    # 通过JS直接获取目标div
    div = driver.execute_script(f'''
        return document.querySelector('section.grid-container.mt-6').querySelectorAll('a')[{idx}].querySelector('div:first-child');
    ''')
    div.location_once_scrolled_into_view
    # 等待元素可见与渲染
    WebDriverWait(driver, 5).until(EC.visibility_of(div))
    # 后续截图逻辑不变

4. 修复高缩放白屏问题

高缩放白屏多因元素未完全进入视口或渲染缓存问题,截图前强制重绘元素:

# 在截图前执行重绘
driver.execute_script("arguments[0].style.display = 'none'; arguments[0].style.display = 'block';", div)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 19:05:06