PowerShell 实现批量下载文件
0.00
★312次@
A:
PowerShell 实现批量下载文件
# 输出欢迎信息
function Write-Welcome {
Write-Output "---------------------------------------------"
Write-Output "未来之窗批量文件下载器 PowerShell版"
Write-Output "@product spany-down-ps"
Write-Output "@author felix"
Write-Output "@date 2019-04-19"
Write-Output "---------------------------------------------"
Write-Output ""
}
#region 接收输入
# 接收是否输入
function ReadInput_YesOrNo {
param([string]$message, [switch]$defaultValue)
while($true) {
$input = Read-Host $message
if(![String]::IsNullOrWhiteSpace($input)) {
if($input -eq 'y' -or $input -eq 'n') {
return $input -eq 'y'
}
}
if($defaultValue) {
return $args -eq $true
}
}
}
# 接收文本输入
function ReadInput_Text {
param([string]$message, [string]$defaultValue)
while($true) {
$input = Read-Host $message
if(![String]::IsNullOrWhiteSpace($input)) {
return $input.Trim()
}
if($defaultValue) {
return $defaultValue
}
}
}
# 接收整数输入
function ReadInput_Integer {
param([string]$message, [int]$minValue=[Int32]::MinValue, [int]$maxValue=[Int32]::MaxValue)
$defaultValue = $message
while($true) {
$input = Read-Host $message
if([String]::IsNullOrWhiteSpace($input)) {
$message = $defaultValue
continue
}
$input = $input.Trim()
[int]$result = 0
if(![Int32]::TryParse($input, [ref]$result)) {
$message = "必须输入一个整数"
continue
}
elseif($result -lt $minValue -or $result -gt $maxValue) {
$message = "整数范围必须是 $minValue-$maxValue,请重新输入"
continue
}
return $result
}
}
# 接收URL输入
function ReadInput_Url {
param([string]$message, [string]$defaultValue)
$defaultMessage = $message
while($true) {
$input = Read-Host $message
if([String]::IsNullOrWhiteSpace($input)) {
if($defaultValue){
return $defaultValue
}
$message = $defaultMessage
continue
}
$input = $input.Trim()
if($input.Length -lt 18 -or !($input -clike 'http://*' -or $input -clike 'https://*')) {
$message = "URL格式不正确,请重新输入"
continue
}
return $input
}
}
# 接收路径输入
function ReadInput_Path {
param([string]$message, [string]$defaultValue, [bool]$createIfNotExist = $true)
$defaultMessage = $message
$path = ""
while($true) {
$input = Read-Host $message
if(![String]::IsNullOrWhiteSpace($input)) {
$path = $input.Trim()
}
elseif($defaultValue) {
$path = $defaultValue
}
else {
$message = $defaultMessage
continue
}
try {
$dir = New-Object -TypeName System.IO.DirectoryInfo($path) # 新建DirectoryInfo对象,如果抛出异常说明路径非法
if($createIfNotExist -and !$dir.Exists) { # 或者 Test-Path -Path $path 但无法识别路径中的括号
$path = $dir.FullName
New-Item -Path $path -ItemType Directory | Out-Null
}
} catch [System.ArgumentException], [System.IO.PathTooLongException] {
$message = "该路径不合法,请重新输入"
$path = ""
continue
}
return $path
}
}
#endregion
# 构建URL列表
function BuildUrlList {
param([string]$urlFormat, [int]$start, [int]$end, [int]$len)
if(!$urlFormat.Contains("(*)")) {
return ,$urlFormat
}
$list = @()
$last = $end + 1
for($i = $start; $i -lt $last; $i++) {
$tmp_url = $urlFormat -replace "\(\*\)",("{0:D$len}" -f $i) ## 或者 $i.ToString("D$len")
$list += $tmp_url
}
return $list
}
[int]$script:completed = 0 # 下载完成数量
[int]$script:succeed = 0 # 下载成功数量
# 开始下载(普通方法)
function StartDownload {
param([array]$urlList, [string]$path, [string]$referer)
$last = $urlList.Count
$watch = Measure-Command {
for($i = 0; $i -lt $last; $i++) {
DownloadItem -url $urlList[$i] -path $path -referer $referer
Start-Sleep -Milliseconds 200 # 延迟0.2秒
}
}
$failed = $script:completed - $succeed
$elapsed = [Math]::Round($watch.TotalMilliseconds/1000, 2) # 总计耗时(秒)
Write-Output ""
Write-Host "总共下载 $script:completed,成功 $script:succeed,失败 $failed,耗时 $elapsed s" -ForegroundColor Red -BackgroundColor Yellow
$script:completed = 0
$script:succeed = 0
}
# 下载单个文件
function DownloadItem {
param([string]$url, [string]$path, [string]$referer)
$url_file = $url.Substring($url.LastIndexOf('/') + 1);
if($referer.Contains("(*)")) {
$referer = $referer -replace "\(\*\)", $url
}
try {
$tmpFileName = [System.IO.Path]::GetTempFileName()
$destFileName = [System.IO.Path]::Combine($path, $url_file)
$watch = Measure-Command {
# 下载文件到临时文件夹
Invoke-WebRequest -Uri $url -Method Get -Headers @{"Referer"=$referer} -UserAgent "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36" -TimeoutSec 120 -OutFile $tmpFileName
# 将临时文件移动到目标文件夹
Move-Item -Path $tmpFileName -Destination $destFileName -Force
}
$script:succeed += 1
$fileLength = [Math]::Ceiling((Get-Item -LiteralPath $destFileName).Length / 1024.0)
$elapsed = [Math]::Round($watch.TotalMilliseconds)
# 下载成功!12.jpg - 115KB/2356ms
Write-Host "下载成功!$url_file - $fileLength KB/$elapsed ms" -ForegroundColor Green
} catch {
Write-Error $PSItem.ToString()
} finally {
$script:completed += 1
}
}
# 主函数 运行 AppStart 即可启动
function AppStart {
Clear-Host
Write-Welcome
$urlFormat = ReadInput_Url -message "输入URL(含通配符,例如 https://51.onelink.ynwlzc.cn/cyberwin-static/cwpd_static/./2020/(*).jpg)"
$start = ReadInput_Integer -message "通配符数字开始(0~200)" -minValue 0 -maxValue 200
$end = $start + 200
$end = ReadInput_Integer -message "通配符数字结束($start~$end)" -minValue: $start -maxValue $end
$len = ReadInput_Integer -message "通配符数字长度(1~5)" -minValue: 1 -maxValue 5
$referer = ReadInput_Url -message "输入Referer为破解防盗链(如果Referer中含有通配符(*),则将被当前URL替换,如无须Referer则直接回车)" -defaultValue "https://www.baidu.com/visit"
Write-Output ""
$urlList = BuildUrlList -urlFormat $urlFormat -start $start -end $end -len $len
if($urlList.Count -gt 0) {
Write-Output "URL列表如下:"
foreach($url in $urlList) {
Write-Output "`t$url"
}
Write-Output ""
if(ReadInput_YesOrNo -message "是否开始下载?(y/n)") {
$path = ReadInput_Path -message "输入文件存储路径(例如 E:\album\travel)"
Write-Output ""
StartDownload -urlList $urlList -path $path -referer $referer
}
} else {
Write-Warning "不能创建URL列表,请核对参数!"
}
Write-Output ""
Write-Output "按任意键退出..."
[System.Console]::ReadKey($true) | Out-Null
}
AppStart
硬件app