Selenium截图自定义字体表格异常:无头模式不加载字体、正常模式宽度错误
Selenium截图:无头模式字体加载与正常模式宽度异常问题解决
问题重现
原始Python代码
from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from PIL import Image import io import os chrome_options = Options() chrome_options.add_argument("--headless") chrome_options.add_argument("--window-size=1920x1080") chrome_options.add_argument("--force-device-scale-factor=1") driver = webdriver.Chrome(options=chrome_options) path = os.path.abspath("table_minimal.html") driver.get(f"file://{path}") table = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.TAG_NAME, "table"))) png = table.screenshot_as_png im = Image.open(io.BytesIO(png)) im.save("table.png") driver.quit()
对应的HTML文件(table_minimal.html)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&display=swap" rel="stylesheet"> <style> table { font-family: 'Montserrat'; font-size: 20px; } </style> </head> <body> <table><tr><td>Text in the table</td></tr></tbody></table> </body> </html>
遇到的问题:
- 启用
--headless无头模式时,截图未应用自定义Montserrat字体 - 移除
--headless后,字体正常但表格宽度识别错误
一、无头模式下自定义字体加载问题解决
关键调整点
添加无头模式渲染与资源加载参数
无头模式默认渲染配置会限制字体加载,补充以下参数确保字体正常加载、渲染:chrome_options.add_argument("--no-sandbox") chrome_options.add_argument("--disable-dev-shm-usage") chrome_options.add_argument("--font-render-hinting=full") chrome_options.add_argument("--enable-font-antialiasing") # 模拟正常浏览器UA,避免字体CDN拦截 chrome_options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36")等待字体加载完成再截图
原代码仅等待表格元素出现,但字体可能仍在加载中,需通过JavaScript等待字体加载完成:# 等待表格元素出现 table = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.TAG_NAME, "table"))) # 等待所有字体加载完成 WebDriverWait(driver, 10).until(lambda d: d.execute_script("return document.fonts.ready"))
修改后的完整Python代码
from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from PIL import Image import io import os chrome_options = Options() chrome_options.add_argument("--headless") chrome_options.add_argument("--window-size=1920x1080") chrome_options.add_argument("--force-device-scale-factor=1") # 新增的字体渲染与资源加载参数 chrome_options.add_argument("--no-sandbox") chrome_options.add_argument("--disable-dev-shm-usage") chrome_options.add_argument("--font-render-hinting=full") chrome_options.add_argument("--enable-font-antialiasing") chrome_options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36") driver = webdriver.Chrome(options=chrome_options) path = os.path.abspath("table_minimal.html") driver.get(f"file://{path}") table = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.TAG_NAME, "table"))) # 等待字体加载完成 WebDriverWait(driver, 10).until(lambda d: d.execute_script("return document.fonts.ready")) png = table.screenshot_as_png im = Image.open(io.BytesIO(png)) im.save("table.png") driver.quit()
二、正常模式表格宽度识别异常的原因
页面布局未完全稳定
正常模式下Chrome窗口渲染流程更复杂,表格布局可能还未计算完成就被截图,导致宽度偏差。可等待页面完全加载:WebDriverWait(driver, 10).until(lambda d: d.execute_script("return document.readyState === 'complete'"))默认样式差异
正常模式下Chrome会给body、table添加默认样式(比如body的margin、table的border-spacing),影响表格实际渲染宽度。如需精确控制,可在CSS中明确设置:body { margin: 0; padding: 0; } table { font-family: 'Montserrat'; font-size: 20px; width: fit-content; border-collapse: collapse; }窗口缩放与DPI设置
正常模式下浏览器可能受系统DPI缩放、窗口缩放比例影响,导致元素渲染尺寸与代码设置的window-size不一致,进而影响截图宽度。可通过--force-device-scale-factor=1参数强制统一缩放比例,和无头模式保持一致。
内容的提问来源于stack exchange,提问作者Sil
相关产品推荐
相关产品推荐

