资讯动态

wget高级用法实战:断点续传、限速与递归镜像

发布时间:2026/10/16 3:36:29 来源:尧图企业网站定制
前阵子在机房处理一个迁移任务需要从内部对象存储拉下来一个将近 8GB 的压缩包机器带宽明明有 1Gbps可 wget 默认跑起来速度一直上不去进度条纹丝不动最后还因为 SSH 会话断开导致下载中断又得从头再来。后来我把命令换成带断点续传和后台运行的写法再搭配限速、重试和会话日志整批下载任务一下子变得可控了。wget 就是这么个工具表面上看就是下载文件但真正到了生产环境它能不能断点续传、会不会自动重试、能不能压带宽、能不能递归拉整个目录直接决定你是花十分钟还是花一个晚上。这篇我打算集中聊一聊 wget 里那些运维和开发真正用得上、却常常被忽略的操作包括断点续传、后台任务、限速控制、批量 URL、递归镜像、认证伪装、超时重试以及几个我已经在脚本里稳定跑了大半年的组合实战用法。纯手打经验适合每天要跟下载、同步、采集打交道的人。1. 为什么你的 wget 总是慢先把最基本的姿势摆对1.1 默认行为决定了下限大家最常用的wget url其实只做了一件事把资源完整拉到当前目录文件名取 URL 的最后一段。这个命令本身没有问题问题在于它的默认行为实在太朴素了——不强制走 IPv4、不设置合理的超时、没有断点续传、也没有并发一旦网络有波动前面拉了一半的数据就全部作废。举个例子wget https://example.com/backup/data.tar.gz执行后它会在当前目录生成data.tar.gz。如果文件已经存在默认动作是生成一个带序号的新文件比如data.tar.gz.1而不是覆盖。很多刚开始用 wget 的人都会在这里困惑为什么我下了两次目录里有三个文件这就是默认行为造成的。另外很多人不知道 wget 默认会从/etc/resolv.conf里取 DNS 配置解析出来的 IP 有可能是 IPv6。某些老旧的服务器 IPv6 链路质量不佳导致连接建立得很慢实际下载速度也上不去。这时候加一个-4参数强制走 IPv4往往立竿见影。我处理过不少wget 速度只有几十 KB/s的工单最后查下来都是主机优先解析到 IPv6 地址而 IPv6 出方向带宽被限流-4一加就恢复到了满速。1.2 影响速度的几个隐藏因素除了 IPv4/IPv6还有几个因素对下载速度影响很大知道之后你就不会动不动怪运营商了。第一是 TLS 握手和证书校验。如果你的服务器访问外网需要走代理或者对方站点证书链不完整wget 每次都可能在握手阶段耗费一两秒。单次下载还好批量下载一百个小文件时这个开销会被放大到令人抓狂的程度。我在批量场景下一般先看对方支不支持 HTTP 协议头里的条件请求再看有没有必要保留证书校验。第二是重定向处理。有些下载链接会 302 跳转到 CDNwget 默认是跟随重定向的但如果你在脚本里写死了-O target.tar.gz而重定向后的文件名和预期不一致有可能出现下载下来是个 HTML 错误页的情况。判断方法很简单file target.tar.gz看一下文件类型如果显示HTML document那基本就是被反爬或者被负载均衡拦了。第三是并发模型。wget 不支持单个命令同时下载多个文件它只能串行处理 URL。要提升多文件场景下的整体吞吐要么用xargs -P拉多个 wget 进程要么干脆上 aria2。这里先不展开后面批量下载的部分会给出具体写法。1.3 先学会看输出再谈优化wget 的默认进度条在终端里很好看但在脚本日志里就是灾难。它不断用回车刷新同一行日志文件里全是碎片化的进度信息根本没法排查问题。所以我的习惯是交互式终端里就用默认进度条写进 cron 或 CI 的脚本一律加--progressdot:giga这样输出变成一行一个点每 1MB 一个点比如wget --progressdot:giga https://example.com/backup/large_file.bin输出大概长这样0K .......... .......... .......... ..两个点一组的节奏肉眼扫一遍就能看出下载是否在推进。日志场景里再配合-a download.log把输出追加到指定文件而不是污染 stdout。后面讲日志和自动化的时候我会再聊聊怎么用好这几个参数。2. 断点续传、后台下载和日志把半路断掉的下载救回来2.1 一个-c参数解决断线焦虑下载最难受的事情不是慢而是慢了半天断掉之后从头再来。wget 的-ccontinue参数就是为了这个场景设计的。-c的作用是让 wget 检查本地已有文件的大小然后通过 HTTP 头里的Range字段向服务器请求从某个字节偏移开始继续传输。使用的时候有几个前提服务器必须支持 Range 请求。绝大多数静态文件服务器和对象存储都支持但某些动态生成的接口不一定支持这时候-c不会报错而是静默变成从头下载最后给你一个覆盖掉的文件。本地文件必须和服务器上是同一个文件。如果你本地已经有一个名字相同但内容完全不同的文件带上-c会让 wget 去请求从本地文件大小这个偏移开始的数据结果拼出一个损坏的文件。不要在下载完成后再次使用-c。wget 判断文件已完整时会直接跳过但如果恰好有个同名文件且内容不完整就很容易引发困惑。实际使用时我喜欢把-c和--tries一起写表示断掉之后自动重试若干次wget -c --tries5 --timeout30 https://example.com/data/jdk-21.tar.gz--tries5不是开玩笑的它会在网络错误、超时、连接被重置的时候自动重新发起连接并且断点续传会接着上次的位置走不会重复下载已经拿到的数据。这在弱网环境下载大文件时体验可以说是质变。2.2 用-b把任务丢到后台运维场景里我经常要在一台跳板机上拉数据但 SSH 会话说断就断。如果直接前台跑 wget会话一断进程就没了。这时候两个选择用tmux或者screen挂住会话或者直接让 wget 自己后台化。wget 提供的-b参数就是后台模式它会做一个 fork把进程放进后台然后在当前目录生成一个wget-log文件记录输出。wget -b -c https://example.com/data/large_dataset.zip命令执行后会立刻打印进程号并返回 shell。你可以用tail -f wget-log观察进度也可以放任不管。相比 tmux-b的好处是跟 shell 会话完全解耦只要机器不重启进程就一直跑。坏处是多进程之间的资源不好管理所以我自己更常用的组合是nohup wget -c ... download.log 21 这样日志我自己控制路径进程不受 HUP 信号影响后续 grep 起来也方便。注意后台运行时 wget 的默认输出还是进度条刷屏所以一定要配合--progressdot:giga否则wget-log里全是回车符看着非常崩溃。正确的后台姿势是nohup wget -c --progressdot:giga https://example.com/data/java_mid_ver.tar.xz dl.log 21 这样日志干净断点续传也开着哪怕第二天来看只要服务器上的文件还在随时能接着跑。2.3--spider这个彩蛋只探测不下载--spider是一个很容易被忽略的参数它不会下载文件只是发起请求检查链接是否有效、服务器是否支持 Range、资源是否存在。做批量链接巡检非常有用。wget --spider https://example.com/path/to/file.zip返回码 1 表示有异常0 表示正常。把这个命令塞进巡检脚本就能每天自动探测几百个 URL 是否还活着。我做过一个简单的巡检脚本循环读取一份 URL 清单对每个链接执行wget --spider --timeout5把返回码非零的记录下来比某些商业监控工具还顺手。有一点要提醒--spider在部分服务器上会触发访问日志如果对方接口有访问频率限制记得加上--wait1之类的间隔否则容易被封。反正探测是低频操作间隔大点没坏处。3. 限速、重试和超时自动化脚本里不能忽略的细节3.1 用--limit-rate把下载节奏握在自己手里很多开发同学第一次看到--limit-rate的反应是我只想越快越好为什么要限速真实原因是服务器上往往同时跑着业务服务你用 wget 全速拉一个大文件可能把出口带宽打满数据库备份、远程调用全部跟着超时。限速参数每秒都会平滑地限制速度比如wget --limit-rate5m https://example.com/backup/whole_site_assets.tar.gz这个命令把速度限制在 5MB/s 左右。我一般用来做白天低峰期的数据迁移限制在 8MB/s既能保证任务在几小时内完成又不影响线上接口的响应。晚高峰时段可以放宽到 20MB/s反正根据业务情况动态调整。限速的实际效果受 TCP 窗口和服务器发送策略影响不会像节流阀一样精准但整体非常接近设定值。另外一个容易踩的坑是--limit-rate的单位缩写是 k、m 等注意小写 m 和大写 M 的区分wget 是区分大小写的--limit-rate5m是 5MB/s--limit-rate5M按文档是 510241024 bit严格来说文档里推荐用小写字母测试下来5m最直观我就不纠结这些字面大小写了反正生产脚本里统一用--limit-rate2m这种写法大家约定俗成也能看明白。3.2 超时参数比你想的更关键wget 默认如果服务器没有响应可能会一直等下去。在脚本里这就是隐患一个卡住的下载任务会把整个自动化流程拖死。所以只要你写脚本就必须显式设置超时。超时分为三个维度--timeout30设置连接、读取等所有阶段的整体超时时间。--connect-timeout10只限制 TCP 连接建立的阶段。--read-timeout30限制两次数据读取之间的最大间隔防止服务器半死不活。我推荐的组合是wget -c --timeout30 --tries5 --waitretry10 https://example.com/packages/app.tar.gz--waitretry10表示每次重试之前等待 10 秒避免网络一抖动就疯狂重连把服务器打挂。这个参数在网络不稳定的生产环境里非常实用我见过有同事不加--waitretry结果下载任务每秒重试一次最终被对方限流策略禁掉了 IP。3.3 重试次数背后的真实逻辑--tries0表示无限重试听起来一劳永逸但如果服务器彻底返回 404无限重试也是浪费时间。我的建议是有明确的网络抖动预期时用--tries20搭配--waitretry15处理那种间歇性断流如果是下载固定版本文件--tries3就够了失败就让脚本报警并结束避免无限循环卡在错误上。重试和断点续传搭配使用时有一个隐藏行为要清楚wget 在重试时对于已经下载了一部分的文件会默认尝试继续下载剩余部分。这个行为并不是所有版本都稳定GNU wget 1.21 之前的老版本在某些场景下会重新下载整个文件。如果在生产环境里发现断点续传不生效优先检查 wget 版本wget --version。太旧的版本该升级还是要升级别在这种基础工具上省事。3.4--wait和--random-wait礼貌地抓取--wait5是每次请求之后强制间隔 5 秒。--random-wait是在--wait基础上随机加 0.5 到 1.5 倍的时间比如指定--wait3 --random-wait实际间隔会在 3 秒到 6 秒之间随机浮动。这个主要是给批量抓取场景用的目的是让请求间隔不像固定节拍器降低被识别为脚本扫描的概率。如果你只是下载一个文件这两个参数完全不用管。但如果你要写一个会持续十几分钟、访问几百个 URL 的采集脚本这两个参数能让对方服务器舒服得多你的 IP 也更安全。固定频率的请求在服务端日志里非常扎眼稍微带点随机性反而自然。4. 批量下载和 URL 列表一次拉下一百个文件4.1 用-i读取 URL 清单当你要下载的文件不是一个而是几十上百个时手动复制链接就太傻了。wget 支持用-i指定一个输入文件里面每一行放一个 URL然后 wget 会逐条下载。wget -i urls.txturls.txt的格式很简单https://example.com/files/a.zip https://example.com/files/b.zip https://example.com/files/c.zip这个命令会一次性串行下载所有链接。串行的问题在于如果第一个文件特别大第二个文件就得耐心等。想要多文件并行可以在 shell 层面用xargscat urls.txt | xargs -n 1 -P 5 wget -c -q-P 5表示同时跑 5 个 wget 进程整体吞吐会高不少。现代 Linux 发行版都带 xargs这个方案零依赖比写复杂的后台任务管理简单可靠。如果你需要把每个文件下载到不同目录-i就满足不了你了因为-i是统一输出到当前目录的。这时候我一般把-i换成while read循环在循环里用-P指定目录灵活得多while read -r url; do wget -q -P /data/raw_files $url done urls.txt4.2 用 shell 的花括号和序列生成 URL有一类 URL 是带编号的比如file_01.zip、file_02.zip一直到file_50.zip。你完全不需要在清单里手写 50 行shell 的花括号展开就能生成wget https://example.com/pack/file_{01..50}.zip注意花括号展开是 bash 的功能不是 wget 的功能。zsh 用户也支持写法类似。如果你的脚本用的是 sh就要小心因为有些 sh 实现不支持这个展开。稳妥做法还是用 seq 生成清单for i in $(seq -w 1 50); do echo https://example.com/pack/file_${i}.zip done urls.txtseq -w 1 50会输出01到50配合 URL 模板就能生成完整清单。这个写法兼容性最好在任何 shell 里都能跑。4.3 配合--content-disposition处理服务端文件名有很多下载链接长得其实是接口比如https://example.com/download?id12345这时候-O指定文件名是必须的。但如果你用-i批量下载此类接口并且希望文件名从服务器返回的Content-Disposition头里读取那就要加--content-dispositionwget --content-disposition -i download_links.txt这个参数让 wget 在服务器响应中寻找Content-Disposition: attachment; filename...字段并以此作为保存文件名。我经常用它对接企业内部的临时下载接口那些接口往往不带文件名信息返回的 URL 是一串乱码加上这个参数就方便多了。需要留意的坑是某些老版本 wget 对Content-Disposition里的中文文件名支持不好会保存成乱码。如果遇到这种情况要么在服务端处理文件名编码要么干脆用循环加-O手动指定文件名别硬扛。5. 递归下载、镜像目录和 HTML 后处理把整个站点目录搬到本地5.1 递归参数组合-r -l inf -np递归下载是 wget 被低估的能力之一。很多运维不知道wget 能把一个目录页面上链接到的所有资源都抓下来甚至能完整镜像一个静态站点。最基本的递归参数是-r配合-l指定递归深度。-l 1表示只抓当前页面里直接链接的文件-l 2表示还能抓子页面里的链接。如果不加-npno parentwget 有可能沿着链接跑到父目录也就是上级页面去这在镜像时经常导致多抓出大量无关文件。推荐的一种组合wget -r -l 5 -np -k -p https://example.com/docs/拆解一下-r开启递归。-l 5最多往下追 5 层链接防止无限深入。-np不追到父目录只抓当前路径下的内容。-k把页面里的链接转换成指向本地文件的相对路径方便离线浏览。-p下载页面所需的全部资源包括 CSS、图片、JS。这个组合我经常用来拉取内部文档站到本地做离线备份。抓完之后直接用浏览器打开本地的index.html就能浏览不需要再起一个 HTTP 服务。5.2--cut-dirs控制目录层级别让路径嵌套太深递归下载时 wget 默认会把 URL 的路径结构原样映射成本地目录。比如https://example.com/docs/guide/chapter1.html会被存成example.com/docs/guide/chapter1.html。如果你只想保留chapter1.html或者想去除前面几层无用路径就需要--cut-dirs。wget -r -np -nH --cut-dirs3 https://example.com/a/b/c/asset/-nH表示不创建以主机名命名的目录。--cut-dirs3表示去掉 URL 路径里的前 3 层。这样下载下来的文件就会直接放在当前目录下对应的子路径里清爽很多。这个参数对脚本处理很重要因为它直接影响你后面find或tar打包时的路径规划。5.3 增量镜像-m -N组合如果站点内容会更新你希望每次只下载有变动的文件那就要用-m镜像模式和-N时间戳判断。wget -m -np -k -p -N https://example.com/website/-m其实是-r -N -l inf的快捷方式-N的意思是不下载本地已经存在且服务器端没有更新的文件。这个组合跑第二次时只会拉新增和改动的文件速度非常快。不过要注意-N依赖服务器返回正确的Last-Modified头如果对方服务器时间有问题这个机制会失灵出现每次都全量下载的情况。我自己的经验是增量镜像最好配合 cron 跑但每次运行前先检查磁盘剩余空间防止异常情况下镜像目录膨胀把磁盘撑爆df -h /data/mirror | tail -1另外-m和-k一起用时wget 会重写本地 HTML 里的链接这个重写本身是幂等的但如果你存放镜像的目录被 NFS 挂载到多个机器上小心并发执行同一个镜像任务会带来文件锁和半写状态问题。给任务加个简单的锁文件是个好习惯比如if [ -f /tmp/mirror_site.lock ]; then echo Mirror task is already running. exit 1 fi touch /tmp/mirror_site.lock # wget -m ... rm -f /tmp/mirror_site.lock5.4 常见失败原因HTML 里的相对链接与绝对链接递归镜像失败的原因十有八九是页面里的链接写得太绝对。比如页面上写着a hrefhttps://example.com/assets/main.css而你的-np限制的是路径前缀只要链接在同一个域名下还是会被抓下来。但如果页面里混入了外链比如统计代码、第三方字体wget 默认是不跨越域名去抓取的除非你显式指定-H允许跨越主机。如果你确实需要保留外链资源的离线版本我给的建议是等镜像完了之后用一条命令把外链替换成占位符避免离线打开时出现一堆 404 等待超时find /data/mirror -name *.html -exec sed -i s|https://stats.example.com|/placeholder|g {} 这一步算是一个实用小技巧能大幅提升离线浏览体验。递归抓站是有责任边界的别把范围扩得太大抓到某个机构或者个人的侵权资源那就不是工具的问题了。6. 身份认证、请求伪装与证书处理的实用细节6.1 基本认证和隐藏参数很多内网资源用 HTTP Basic Auth 保护wget 的--user和--password就是干这个的wget --user admin --password secret https://example.com/private/data.xlsx密码里有特殊字符时一定要用单引号包裹否则 shell 会把它做通配符或转义处理。如果你不想在命令里暴露密码可以用--user不带--passwordwget 会交互式提示你输入密码。这个适合在服务器上手动操作避免密码出现在 shell 历史里。6.2 自定义请求头和 User-Agent有些资源服务器会对默认的Wget/1.21.1请求头比较敏感你一访问就返回 403。最简单的解决办法是伪装 User-Agentwget -U Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36 \ https://example.com/files/report.pdf-U是--user-agent的简写。注意不要乱用真实浏览器 UA 去突破访问限制我这里说的伪装场景是某些服务器确实因为安全策略拦截了未知 UA你的目的是正常下载公开文件。自定义任意请求头用--headerwget --header Accept-Language: zh-CN,zh;q0.9 \ --header Referer: https://example.com/listing \ https://example.com/download/file.zip有些资源站做了 Referer 防盗链必须带着站内页面地址才能下载第二个--header就是应对这种情况。6.3 证书问题的处理--no-check-certificate别乱用内网环境经常有自签名证书wget 默认校验会失败报self-signed certificate。处理方式有两种一是把证书加到系统信任区二是在命令里临时关闭校验wget --no-check-certificate https://internal.example.com/artifact.tar.gz这里必须说明--no-check-certificate会跳过证书链验证有中间人攻击风险只能在内网可控环境使用。公网下载安全补丁这些场景一定不能加这个参数否则你下载到的内容可能是伪造的。正确做法是拿到对方的证书文件放到/etc/pki/ca-trust/source/anchors/下然后执行update-ca-trust之后 wget 就能正常访问了。这个方法比永久关闭校验安全得多也更专业。6.4 会话恢复下载时的认证注意断点续传 认证下载时wget 对已下载的部分不会再发送认证请求而是直接用 Range 续传。大多数服务端都能处理好Authorization头和 Range 一起出现但也有部分老旧的 HTTP 服务在认证后丢弃 Range 信息导致续传出来的文件损坏。遇到这种情况我的排查思路是先完整验证下载后的文件哈希如果不对就清掉本地文件重新完整下载同时把这个服务端的兼容性问题记录下来后续针对该服务端走全量下载或改用脚本分段获取。文件校验码是底线别省这一步。我在脚本里习惯性地用sha256sum校验下载结果一旦不匹配立刻报警而不是默默接受一个损坏的文件。7. 组合实战几个已经在我机器上稳定跑的 wget 用法7.1 带时间戳的增量同步备份线上服务器每天会生成一批日志文件我通过一条 wget 命令在备份机上做增量拉取。核心是-N加时间戳判断wget -r -np -nH -N --cut-dirs2 \ --progressdot:giga \ https://prod-log.example.com/logs/2025/ \ -P /backup/logs/这条命令只下载 2025 目录下比本地更新的文件。第一次全量之后每次只拉新增。相比走 rsyncwget 做 HTTPS 拉取的优势是不需要在备份机上开 SSH 权限给客户端只要对方提供一个只读的 Web 目录就能完成同步。缺点是没有 rsync 的增量校验和软链接处理所以我一般再叠加一层完整性审计。7.2 下载完成后自动校验并解压下载压缩包不是终点很多流程还要自动解压。用串联命令时一定注意wget 下载到了临时文件名再改名解压避免半截文件被解压出错误数据wget -c -O package.tar.gz https://example.com/dist/package.tar.gz \ sha256sum -c checksums.txt \ mkdir -p /opt/package tar -xzf package.tar.gz -C /opt/package这里-O package.tar.gz指定输出文件名。要注意-O和-c一起使用时wget 会把续传目标写到这个文件名上比默认文件名更可控。校验和解压分成三步每步失败都直接中断不会留下错误的半安装状态。7.3 从 URL 列表里挑出特定扩展名的文件有时候你给的不是文件列表而是某个目录的索引页。这时用-A指定只接受的扩展名能让递归下载只拉你真正需要的文件wget -r -np -A *.tar.gz,*.zip -l 3 https://example.com/releases/-A的匹配是文件名后缀匹配不要写成-A tar.gz要带*才比较符合直觉。反向排除用-R比如-R *.html,*.tmp。这两个参数在抓取资源包时能帮你过滤掉一堆无关页面非常省事。7.4 动态生成带认证头的下载命令对接需要 Token 的下载接口时我经常在脚本里拼一个请求头TOKEN$(ssh somewhere cat /run/secrets/download_token) wget --header Authorization: Bearer $TOKEN \ --content-disposition \ https://api.example.com/v1/files/export?id20250101Token 从专门的密钥文件读取不写死在脚本里避免密钥跟着脚本仓库泄露。下载成功后立刻把 Token 变量 unset 掉日志里也不要打印包含 Token 的命令。这些细节才是在生产环境长期稳定运行的关键。8. 我对 wget 的一些偏见和踩坑心得8.1 wget vs curl什么时候不选 wgetwget 和 curl 功能重叠不少但各自侧重点不一样。wget 的优势在于递归、批量 URL 列表、断点续传和镜像能力天生面向把资源拿下来这件事。curl 的优势在于协议广、上传支持好、各种请求方法和请求头控制更精细适合调试接口。我的原则是下载场景优先 wget接口调试优先 curl。如果你主要做 API 对接非要 wget 也不是不行但支持度和社区生态明显不如 curl。8.2 永远检查最终文件的真实性这个提醒我已经在正文里提过好几次但还是要单独拉出来讲不管命令有多熟练下载完成后一定要验证文件类型和哈希。一条简单的file命令能帮你发现 90% 的假下载。file downloaded.bin sha256sum downloaded.bin我见过一个诡异案例某个开发写的脚本下载了三天每天成功结果打开文件全是 HTML 错误页面只有 400 字节。根因是 CDN 节点在源站故障时返回了统一的错误页wget 认为 200 就是下载成功不会做内容类型检查。从那以后我的所有下载脚本里都会加这行校验。8.3 别图省事版本和帮助信息要看wget 的版本差异在某些细节上很明显。GNU wget 和 BusyBox wget 的参数支持度完全不同BusyBox 的 wget 连--limit-rate都没有。在 ARM 路由器、嵌入式设备上写脚本时先跑一下wget --help | head看看当前版本支持哪些参数。跨平台脚本我一般先探测参数支持情况再决定是否退回到兼容写法。8.4 最后的实用小技巧把失败任务自动重跑最后分享一个我实际用了很久的技巧把每次 wget 命令的退出码记录下来非零就自动重跑一次两次失败就发告警。实现很简单function download_with_retry() { local url$1 local output$2 local tries0 until wget -O $output $url; do tries$((tries 1)) if [ $tries -ge 2 ]; then echo Download failed after retries: $url return 1 fi sleep 5 done }这个函数配合-c续传基本能扛住绝大多数临时网络抖动同时不会陷入无限循环。把它放到你的公共脚本库里下载任务就稳了。说到底wget 不是只能下载文件它更像是运维工具箱里一把称手的瑞士军刀。断点续传、后台任务、限速、递归、批量、认证、重试这些参数组合起来能覆盖大部分日常下载场景。与其每次下载时都临时查参数不如把一套适合自己的固定写法沉淀成脚本下次直接抄。希望这篇里分享的东西能让你下次面对一堆下载任务时从容很多。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑