使用指南

批量导入

把旧图床或博客里的图片批量转存进 ImgYoung,支持图片地址清单、站点地图、订阅源、网页与 Markdown、HTML 文本,并导出新旧链接对照表。

什么时候用

旧图床要下线,或者博客里的图片散落在各处,想全部收进 ImgYoung,并拿到「旧链接 → 新链接」的对照表去替换文章里的地址。批量导入就是做这件事:

  1. 给出图片地址,或者给出能找到图片的站点、文本。
  2. 确认要导入哪些域名下的图片。
  3. 服务端逐张抓取并入库,完成后下载对照表。

导入的图片归属当前账号,走与上传相同的处理流程:格式白名单、像素预算、EXIF 处理和存储配额照常生效。只想转存一张图时,用URL 转存。

所有登录用户都能使用。普通用户只能看到和操作自己创建的任务;管理员能看到所有人的任务,并能取消、删除任何人的任务,但确认和重试只有创建者能做。整个实例同一时刻只处理一个导入任务,管理员可以借此取消卡住的任务,让后面的任务继续。

新建导入

在侧栏「内容」组打开「导入」,点「新建导入」;也可以在「图片」页点「上传图片」旁的「批量导入」。对话框有三个标签,按手头已有的材料选一个:

标签填什么之后
图片地址图片地址,一行一个直接开始导入
网站站点地图、订阅源或网页地址,一行一个扫描后,确认要导入的域名
文本与文件粘贴 Markdown 或 HTML 文本,或选择文件扫描后,确认要导入的域名

图片地址

每行一个 http 或 https 的图片地址。同一个地址出现多次只导入一次。提交后任务直接进入「导入中」,没有确认步骤。

网站

每行一个地址,类型由抓回的内容决定,不看扩展名:

地址指向处理
站点地图(urlset、sitemapindex,含 gzip 压缩)逐个扫描其中的文章页面;索引里的子站点地图依次展开
订阅源(RSS、Atom)逐个扫描其中的文章页面
每行一个地址的纯文本按文本站点地图处理,逐个扫描
网页扫描这一页
图片直接作为待导入的图片

服务端只展开到文章页面,不会顺着页面里的链接继续抓取。站点地图或订阅源里不属于它所在域名的页面会被跳过,直接填写的网页地址不受这条限制。

任务创建后进入「扫描中」,页面显示已处理的页面数。扫描结束后进入「待确认」。

文本与文件

粘贴文本,或选择一个或多个 .md、.markdown、.html、.htm、.txt 文件。粘贴的文本在报告里记作「粘贴的文本」,文件以文件名为文档名。

文本里的图片若写的是相对路径,在「基准地址」里填文章所在页面的地址,服务端据此补全。没有基准地址,相对路径无法抓取,会列在扫描报告的「无法抓取的引用」里。HTML 里的 <base href> 优先于基准地址。

扫描在提交时完成,任务直接进入「待确认」。

高级选项

三个标签共用,都可以留空:

选项作用
有效期导入图片的有效期。留空时先取你的默认有效期,没有再取全局默认,见生命周期与查重
EXIF剥离或保留元数据。留空时用全局默认,见EXIF 处理
Referer抓取图片时发送的来源页地址,用于有防盗链的旧图床,见防盗链的图床

确认要导入的域名

「待确认」的任务打开后,页面显示:

  • 扫描报告:扫描了多少页面或文档,几页没有找到图片,几页抓取失败(逐条列出地址与原因,站点地图或订阅源的内容无法解析时原因码为 import_listing_invalid),几处图片引用无法抓取(逐条列出),几个页面因不在站点域名下被跳过。
  • 域名表:发现的图片按域名分组,每个域名一行,显示图片数和最多 3 个示例地址,数量多的在前。

默认一个域名都不选。勾选旧图床所在的域名,点「开始导入」:所选域名下的图片进入导入,其余的不导入。可以用「全选」「清空」批量操作。域名表只显示地址文本,不加载缩略图。

没有勾选任何域名时,「开始导入」不可点。扫描没有发现任何图片时,页面显示「没有发现图片」,这时只能删除任务。

一个页面里图片的域名往往不止一个:旧图床、统计图标、第三方头像都会出现在表里。只勾选你要搬走的那个。

导入过程

任务进入「导入中」后,页面显示进度和各状态的数量,失败的条目实时列出,不需要手动刷新。

  • 并发:一个任务同时转存 4 张。这 4 个名额与上传并发上限相互独立,不占用上传频率额度;规划内存时按两者之和估算。
  • 排队:整个实例同一时刻只处理一个导入任务,其余任务按创建先后排队,期间没有进展。
  • 处理流程:每张图抓取后走与上传相同的流程,成功后记下新图片的短 ID。文件名取地址路径的最后一段。
  • 失败:单张图失败不影响其他图,失败原因记在条目上。全部条目处理完后,任务进入「已完成」,即使其中有失败的。
  • 重启:服务重启后,「导入中」的任务从没处理的条目继续,已经入库的图不会重复导入;「扫描中」的任务从头重新扫描。

失败的条目

错误码常见原因处理
url_blocked地址不是公网地址内网地址不能导入,见抓取限制
url_too_large图片超过单图大小上限调大「单图上限」后重试
url_bad_status远端返回了非 2xx,常见于防盗链填写 Referer 后重新创建任务,或确认旧地址是否已失效
url_fetch_failed超时或连接失败稍后重试
url_too_many_redirects重定向超过 5 次检查地址
upload_unsupported_type格式不在白名单内,如 SVG、AVIF无法导入,见格式与上限
upload_invalid_image内容不是可解析的图片检查地址是否真的指向图片
upload_too_many_pixels分辨率超过像素预算调大「像素预算」后重试

页面按错误码显示本地化的说明,并附远端或服务端返回的原文(最长 500 个字符)。每张图最长处理 20 分钟。

重试

任务结束后点「重试」:失败的条目和没处理的条目一起重新进入「导入中」。已经成功的不受影响。任务不会自动重试失败项。

「已完成」「已中止」「已取消」的任务都可以重试;扫描没有完成就中止或取消的站点任务没有候选可以继续,重试会从头重新扫描;没有失败和未处理的条目时重试会被拒绝(import_nothing_to_retry)。

中止

没有可用渠道或数据库等服务端故障时,继续下去只会让后面的图全部同样失败,所以整个任务中止,状态为「已中止」,页面显示原因,没处理的条目保留。存储配额同理:连续 3 张图都因配额不足失败,就认为配额已满而中止;只是某一张图超过剩余额度时,只有这一张失败,后面放得下的图照常导入。先解决问题(调高配额、修复渠道),再点「重试」继续。

取消

「扫描中」「待确认」「导入中」的任务可以取消。正在转存的图片会被中断,没处理完的条目保持待转存,已经导入的图片保留。取消后的任务可以重试。

对照表

任务结束后(「已完成」「已中止」「已取消」),点「下载对照表」选择 JSON 或 CSV。对照表只包含已导入成功、图片仍然存在的条目。新地址是图片的完整访问地址:设置了对外站点地址(base_url)时用它,否则按当前访问的域名生成。

列含义
old_url旧图片的地址
new_url新图片的地址
image_id新图片的短 ID
source引用这张图的页面地址或文档名
raw引用在该处的原文,可能是相对路径,用来在源文章里查找替换
  • CSV:UTF-8,首行是表头,每处引用一行;没有引用位置的图片输出一行,source 与 raw 为空。以 =、+、-、@ 开头的单元格前会加一个单引号,避免用电子表格打开时被当成公式;要按原文精确查找替换时,用 JSON 对照表。
  • JSON:每张图一个对象,所有引用位置嵌套在 references 数组里:
[
  {
    "old_url": "https://old.example.com/img/a.png",
    "new_url": "https://img.example.com/i/R0RjUyP1UW",
    "image_id": "R0RjUyP1UW",
    "references": [
      { "source": "https://blog.example.com/post-1", "raw": "/img/a.png" }
    ]
  }
]

对照表只用于你自己替换文章里的地址,ImgYoung 不会改动源文章。

删除任务

「待确认」「已完成」「已取消」「已中止」的任务可以删除,任务记录、条目和对照表一并删除,已经导入的图片不受影响。「扫描中」「导入中」的任务要先取消。删除前先下载需要的对照表。

限制与注意事项

  • 只扫描静态 HTML:靠脚本渲染出来的图片找不到,这类页面会计入报告里「没有找到图片的页面」。
  • 站点模式给出的是对照表:抓回的是渲染后的网页,不是文章源文件,所以 ImgYoung 不改写文章,由你按对照表替换。
  • 不识别本地文件引用:data: 内嵌图片、本地路径和 Obsidian 的 ![[文件]] 都不是可抓取的地址,会列在「无法抓取的引用」里。本地图片请用上传。
  • 格式:只能导入 JPEG、PNG、GIF 和 WebP;SVG、AVIF 等会以 upload_unsupported_type 失败。
  • 只抓公网地址:与 URL 转存相同,内网地址被拒绝,见抓取限制。
  • 扫描的限制:失败页面与无法抓取的引用在报告里各列出前 1000 条。并发抓取 4 个页面,单个站点地图、订阅源或页面最大 50 MiB,抓取一个地址最长 2 分钟。页面数与图片数不设上限。不读取 robots.txt,请求的 User-Agent 为 ImgYoung/<版本> (+https://github.com/x-haose/imgyoung)。
  • 提交大小:「文本与文件」一次提交的内容不超过 32 MiB,其中每份文档不超过 4 MiB,解析一份文档超过 15 秒会被拒绝。

防盗链的图床

图片抓取时会带 Referer:「高级选项」里填了就用它,没填就用引用这张图的页面地址;两者都没有(例如图片地址清单)就不发。只放行自家页面的旧图床,对不带来源的请求会返回 403 之类的状态码,表现为 url_bad_status。这时在 Referer 里填旧站的首页或文章页地址,重新创建任务。

用脚本调用

导入接口使用登录会话认证,不接受上传 Token。认证方式见接口参考,每个接口的参数与返回见接口参考:后台·批量导入。

登录后创建一个图片地址清单的任务(csrf_token 取自登录响应):

终端
curl -b jar.txt \
  -H "X-CSRF-Token: <csrf_token>" \
  -H "Content-Type: application/json" \
  -d '{"mode": "images", "urls": ["https://old.example.com/img/a.png", "https://old.example.com/img/b.jpg"]}' \
  https://img.example.com/api/admin/imports

下载对照表:

终端
curl -b jar.txt -OJ \
  "https://img.example.com/api/admin/imports/<任务 ID>/mapping?format=csv"

错误码

操作状态码错误码含义
新建400import_input_invalid请求不合法,提示里指出哪一项有问题,例如某个地址不是 http 或 https 绝对地址
新建413import_input_invalid请求体超过 32 MiB
查看、取消、重试、删除、确认、对照表404import_not_found任务不存在,或属于别的用户(管理员能看到所有人的任务)
新建429import_busy文本解析的名额被占满,等待超过 15 秒仍没有轮到,稍后重试
确认、重试403import_owner_only管理员操作别人的任务,这两项只有创建者能做
取消、重试、删除、确认409import_state_invalid任务当前状态不允许这个操作
确认400import_no_selection所选域名下没有待导入的图片地址
重试409import_nothing_to_retry没有失败或未处理的条目

各状态允许的操作:

状态界面显示可以做
scanning扫描中取消
ready待确认开始导入、取消、删除
importing导入中取消
done已完成重试、下载对照表、删除
cancelled已取消重试、下载对照表、删除
aborted已中止重试、下载对照表、删除

条目失败时的错误码见失败的条目。完整的错误码列表见接口参考里的 ErrorCode。

本页目录