PHP Headless Chromium如何将图片保存到本地文件?
PHP Headless Chromium 登录后下载图片的解决方案
当你已经通过Headless Chromium完成登录并加载目标页面后,注入JavaScript获取图片数据依然是当前最可靠的方案——这种方式能直接复用浏览器已有的登录会话,完全规避直接下载src URL时的身份验证障碍,操作简单且高效。
下面是基于常用PHP Headless Chromium库的具体实现:
方案一:通过Canvas将图片转为Base64(适合同源/已允许跨域的图片)
以chrome-php/chrome库为例,登录后注入JS提取图片的Base64编码,再由PHP解码保存到本地:
use HeadlessChromium\BrowserFactory; $browserFactory = new BrowserFactory(); $browser = $browserFactory->createBrowser(); try { $page = $browser->createPage(); // 执行你的登录逻辑(此处省略,你已实现) $page->navigate('https://目标登录页')->waitForNavigation(); // ... 填写账号密码、提交表单等操作 // 导航到包含目标图片的页面 $page->navigate('https://目标图片所在页面')->waitForNavigation(); // 注入JS获取图片Base64数据 $base64Img = $page->evaluate('() => { // 替换为你的img元素选择器,比如"#target-img"或"img[src*="avatar"]" const targetImg = document.querySelector("你的img选择器"); return new Promise(resolve => { const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d"); canvas.width = targetImg.width; canvas.height = targetImg.height; ctx.drawImage(targetImg, 0, 0); // 根据图片实际类型调整,比如image/jpeg resolve(canvas.toDataURL("image/png")); }); }')->getReturnValue(); // 解码并保存到本地 if ($base64Img) { $imgData = base64_decode(explode(',', $base64Img)[1]); file_put_contents('/本地保存路径/图片名.png', $imgData); } } finally { $browser->close(); }
方案二:通过Fetch API获取Blob(解决画布跨域污染问题)
如果目标图片存在跨域限制,使用Canvas会触发"画布污染"错误,此时可以用fetch直接请求图片(浏览器会自动带上登录后的Cookie),再转为Base64:
// 其他代码同方案一,替换注入的JS部分 $base64Img = $page->evaluate('async () => { const targetImg = document.querySelector("你的img选择器"); const response = await fetch(targetImg.src); const blob = await response.blob(); return new Promise(resolve => { const reader = new FileReader(); reader.onloadend = () => resolve(reader.result); reader.readAsDataURL(blob); }); }')->getReturnValue();
补充说明
除了注入JS,也可以通过拦截Chromium的网络请求来捕获图片数据,但这种方式需要在页面加载前预先设置拦截规则,适合提前知晓图片URL的场景。而你的情况是页面已经加载完成,注入JS的方式更直接高效。
内容的提问来源于stack exchange,提问作者Andrei Herford
相关产品推荐
相关产品推荐

