先解除右键限制再提取隐藏图片URL:执行document.oncontextmenu=null等命令恢复右键,再用脚本遍历DOM提取src、backgroundImage、dataset等来源的HTTP图片链接,过滤Base64和Blob后批量下载。

你想直接提取网页中那些右键灰色、长按无反应、甚至Ctrl+U也找不到img标签的原图——这些图往往藏在CSS背景、Canvas绘图、Base64内联、Blob动态注入或JS拼接的URL里,常规保存路径完全失效。
先解除右键与复制限制
很多网站用JavaScript劫持了contextmenu事件,导致右键菜单根本弹不出来,后续所有操作都卡死在这一步。必须优先恢复基础交互能力。
按F12打开开发者工具→切换到Console面板→粘贴执行:document.oncontextmenu = null; document.body.oncontextmenu = null;→回车。
这一步做完,右键就能正常弹出;但注意:仅清除oncontextmenu还不够,有些页面还会监听mousedown并阻止默认行为,若右键仍无效,请补执行:document.removeEventListener('contextmenu', e => e.preventDefault(), true);
定位真实图片地址(含懒加载与动态生成)
解除限制后,图片可能仍无法右键保存,说明它压根没写在 方法一:用选择元素工具直击CSS背景图 方法二:捕获JS动态创建的Blob图片 【若控制台无输出,说明该图未走Blob路径,需换方法】 当你要的是AVIF无损、WebP Lossless或高分辨率PNG,而不是浏览器渲染后压缩过的副本,就必须绕过DOM,从网络请求源头抓取。 第一步:按F12打开开发者工具→切换到Network面板→刷新页面→在Filter栏输入 第二步:在列表中逐个点击图片请求→看Headers里的Content-Type字段→【若显示image/avif且Response头部含VP8X标志,或image/webp且有VP8L标识,才确认为无损源;否则保存下来的可能是有损JPEG】。 第三步:右键该请求→选择“Open in new tab”→新页加载成功后(地址栏不能以data:或blob:开头)→按Ctrl+S→手动将文件名后缀改为.avif/.webp/.png,并取消勾选“自动添加扩展名”→点击保存。 适合公司电脑禁用扩展、或你打算用Motrix/aria2精细控制下载节奏的场景。脚本能穿透懒加载、兼容currentSrc与srcset解析。 按F12打开开发者工具→切换到Console面板→粘贴执行: 控制台输出一个纯净URL数组,复制整段内容(含方括号)→粘贴到文本编辑器→每行一个链接→导入下载工具即可批量拉取。
点击开发者工具左上角「选择元素」图标(箭头形状)→鼠标移到目标图区域单击→右侧HTML面板高亮对应DOM节点→滚动查看style属性,找background-image: url("https://xxx.jpg")里的引号内完整链接。
在Console中执行:const orig = URL.createObjectURL; URL.createObjectURL = function(a) { if (a instanceof Blob && a.type.includes('image')) console.log('Blob image:', orig.apply(this, arguments)); return orig.apply(this, arguments); };→刷新页面并滚动触发懒加载→控制台将打印出所有被创建的图片Blob地址→复制后粘贴到新标签页即可下载。从Network面板直取无损原始资源
img→等待所有请求加载完成。批量提取全部有效图片URL(免插件)
Array.from(document.querySelectorAll('img, [style*="background-image"], [data-src], [srcset]')).flatMap(el => { const urls = []; if (el.src) urls.push(el.src); if (el.currentSrc) urls.push(el.currentSrc); if (el.srcset) el.srcset.split(',').forEach(s => urls.push(s.trim().split(' ')[0])); if (el.style?.backgroundImage) urls.push(...el.style.backgroundImage.match(/url\("([^"]+)"\)|url\('([^']+)'\)|url\(([^)]+)\)/g)?.map(m => m.replace(/url\(|\)|"|'/g, '')) || []); if (el.dataset.src) urls.push(el.dataset.src); if (el.dataset.original) urls.push(el.dataset.original); return urls; }).filter(u => u && u.startsWith('http') && !u.startsWith('data:') && !u.startsWith('blob:'));










