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

Playwright无法加载本地资源,截图为空问题求助

问题原因及解决方法

核心问题

截图空白主要是两个原因叠加导致:

  1. 使用page.set_content加载的页面处于about:blank源,Chromium对该源访问本地文件的权限限制,即使加了启动参数也无法完全绕过,尤其是在headless模式下。
  2. 未等待图片加载完成就执行截图,导致图片还未渲染就被捕获。

具体解决方案

方案1:改用本地HTML文件加载(推荐)

把HTML代码保存成本地文件(比如/home/user/test.html),修改screenshot方法,用page.goto加载file协议路径,而非set_content:

async def screenshot_from_file(self, file_path: str, clip: dict) -> bytes:
    if not self.is_inital: 
        await self.inital_browser()
    page = await self.browser.new_page()
    # Linux/macOS下file协议格式为file:///绝对路径(三个斜杠)
    await page.goto(f"file://{file_path}")
    # 等待图片加载完成并可见
    await page.wait_for_selector("#pic", state="visible")
    buffer = await page.screenshot(clip=clip)
    await page.close()
    return buffer

调用时传入本地HTML文件的绝对路径即可,此时页面处于file协议源,加载本地图片不会有权限问题。

方案2:将图片转为Base64嵌入HTML

如果不想保存本地HTML文件,可以把图片编码成Base64直接嵌入img标签,彻底绕开本地文件访问限制:

import base64

def image_to_base64(img_path: str) -> str:
    with open(img_path, "rb") as f:
        return base64.b64encode(f.read()).decode("utf-8")

# 生成带Base64图片的HTML
img_base64 = image_to_base64("/home/user/picture.png")
html = f'''<!DOCTYPE html>
<html>
<head>
      <meta charset="utf_8">
<body>
      <img id="pic" src="data:image/png;base64,{img_base64}">
</body>
</html>'''

再把这个HTML传入原有的screenshot方法,同时添加等待图片加载的逻辑:

async def screenshot(self, html, clip: dict) -> bytes:
    if not self.is_inital: 
        await self.inital_browser()
    page = await self.browser.new_page()
    await page.set_content(html)
    # 等待图片可见
    await page.wait_for_selector("#pic", state="visible")
    buffer = await page.screenshot(clip=clip)
    await page.close()
    return buffer

方案3:修正file://路径格式并等待加载

如果坚持用set_content,需要确保img的src是正确的file协议格式(三个斜杠),并等待图片加载:
修改后的HTML:

<!DOCTYPE html>
<html>
<head>
      <meta charset="utf_8">
<body>
      <img id="pic" src="file:///home/user/picture.png">
</body>
</html>

然后在screenshot方法中添加等待逻辑(同方案2的wait_for_selector),同时调整Chromium启动参数,移除已废弃的--allow-file-access:

self.browser = await self.playwright.chromium.launch(
    headless=True,
    args=[
        "--no-sandbox",
        "--disable-web-security",
        "--allow-file-access-from-files"
    ]
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 18:43:29