Powershell - 为什么使用 Invoke-WebRequest 比浏览器下载慢得多?

Powershell - Why is Using Invoke-WebRequest Much Slower Than a Browser Download?

提问人:Lloyd Banks 提问时间:2/24/2015 更新时间:9/7/2023 访问量:63810

问:

我使用 Powershell 的方法将文件从 Amazon S3 下载到我的 Windows EC2 实例。Invoke-WebRequest

如果我使用 Chrome 下载文件,我能够在 5 秒内下载一个 200 MB 的文件。在 PowerShell 中使用相同的下载最多需要 5 分钟。Invoke-WebRequest

为什么使用速度较慢,有没有办法在 PowerShell 脚本中全速下载?Invoke-WebRequest

PowerShell Amazon-S3 的 PowerShell-3.0

评论


答:

66赞 Lloyd Banks 2/25/2015 #1

我正在使用

Invoke-WebRequest $video_url -OutFile $local_video_url

我把上面改成了

$wc = New-Object net.webclient
$wc.Downloadfile($video_url, $local_video_url)

这将下载速度恢复到我在浏览器中看到的速度。

评论

3赞 Groostav 8/29/2019
所以我只是运行,它做了一些事情,大概下载了那个文件,但它没有把它放在我的工作目录中......知道它可能去了哪里吗?wc.downloadFile(ibm-s3-url, "./test.tar.gz")
0赞 BryanC 10/13/2019
@Groostav Mine 出现在 c:\windows\system32 中。这并不完全是我在下载到相对位置时首先要看的地方。
1赞 Mark 10/16/2021
@Groostav当前进程的工作目录与 PowerShell 的当前位置不同
1赞 user1875674 11/2/2016 #2

我今天刚刚遇到了这个问题,如果您将 ContentType 参数更改为 application/octet-stream,它会快得多(与使用 webclient 一样快)。原因是 Invoke-Request 命令不会尝试将响应解析为 JSON 或 XML。

Invoke-RestMethod -ContentType "application/octet-stream" -Uri $video_url  -OutFile $local_video_url

评论

3赞 rednoah 11/3/2016
-ContentType仅适用于 AFAIK 请求,因此可能不会产生任何影响。POST
3赞 codewario 1/29/2020
最好使用该参数,但这不会对静态文件产生太大影响。呼叫前设置可大大提高性能。-UseBasicParsing$ProgressPreference = 'SilentlyContinue'Invoke-WebRequest
218赞 TinyTheBrontosaurus 4/19/2017 #3

在不切换的情况下,关闭进度条为我做到了。我从这个线程中找到了答案:https://github.com/PowerShell/PowerShell/issues/2138(jasongin于2016年10月3日发表评论)Invoke-WebRequest

$ProgressPreference = 'SilentlyContinue'
Invoke-WebRequest <params>

对于我在 localhost 上的 5MB 文件,下载时间从 30 秒到 250 毫秒。

请注意,要在活动 shell 中恢复进度条,您需要调用 .$ProgressPreference = 'Continue'

评论

5赞 lanoxx 10/22/2018
对于 100MB 的文件,这会将时间从 10 分钟减少到 2 秒。我希望开发人员能更多地考虑他们的软件架构。
50赞 sakra 1/10/2019
关于如何不实现进度条的课程。
3赞 Danny Tuppeny 8/8/2019
对于我的 280MB 文件,它从 33 分钟变成了 28 秒。疯狂!
30赞 OrangeDog 8/22/2019
似乎进度条在每个字节后更新,这完全是疯狂的。
12赞 CJBS 5/6/2020
简直不敢相信这不是一个参数-ProgressPreferenceInvoke-WebRequest
17赞 BlueSky 11/12/2019 #4

将文件下载到临时目录的单行代码:

(New-Object Net.WebClient).DownloadFile("https://www.google.com", "$env:temp\index.html")

评论

0赞 Martin Prikryl 11/12/2019
这如何回答这个问题?
4赞 BlueSky 11/14/2019
Lloyd 问道:“有没有办法在 PowerShell 脚本中全速下载?这个答案是一句话。下载到 temp 目录是演示这一点的规范方法。
0赞 Martin Prikryl 11/14/2019
Invoke-WebRequest,OP 已经在使用,在内部执行相同的操作。WebClient.DownloadFile
4赞 codeulike 11/14/2020
这实际上是一个很好的答案,由于 Invoke-WebRequest 跟踪自身进度的方式,WebClient.DownloadFile 比 Invoke-WebRequest 快得多
2赞 fl0w 2/10/2021
绝对相关,这恰好解决了 OP 的问题(以及我的:))
25赞 njefsky 8/7/2020 #5

$ProgressPreference = 'SilentlyContinue'我把它从 52 分钟缩短到 14 秒,对于一个 450 M 的文件。 壮观。

评论

1赞 danimal 8/7/2020
请在您的答案中包含更多信息,例如您描述的设置在哪里设置/定义?
1赞 codewario 11/7/2020
这是 PowerShell 的内置首选项变量,用于控制是否为某些操作显示进度条,例如通过 下载文件。这样可以提高性能的原因是 (和 ) 过于频繁地计算下载的字节数(我相信每个字节),因此 cmdlet 在计算已处理的字节数时实际上会变慢。Invoke-WebRequestInvoke-WebRequestInvoke-RestMethod
1赞 Mariusz Pawelski 6/21/2023 #6

不幸的是,Windows Powershell 5.1(Windows 操作系统中包含的版本)上的进度条大大减慢了文件下载速度。在以后的 Powershell 版本上要快得多(我在 Powershell 7.3 上测试了它)。Invoke-WebRequest

IMO,如果您被迫使用 Windows Powershell,那么最好的方法是使用 curl,因为它现在默认包含在 Windows 上。请注意,默认情况下,Windows Powershell 具有别名,因此要运行程序,您需要写信告诉 Windows Powershell 您不想使用别名。curlInvoke-WebRequestcurlcurl.execurl

此命令在 Windows Powershell 5.1 上需要 11 分钟,在 Powershell 7.3 上需要 23 秒:

Invoke-WebRequest -Verbose -Uri "https://download.visualstudio.microsoft.com/download/pr/7c048383-52b1-47cb-91d1-acfaf1a3fcc9/ea510c0bfa44f33cc3ddea79090a51e1/dotnet-sdk-6.0.410-win-x64.exe" -OutFile ".\dotnet-sdk-6.0.410-win-x64.exe"

这需要 15 秒:

curl.exe -fSLo .\dotnet-sdk-6.0.410-win-x64.exe https://download.visualstudio.microsoft.com/download/pr/7c048383-52b1-47cb-91d1-acfaf1a3fcc9/ea510c0bfa44f33cc3ddea79090a51e1/dotnet-sdk-6.0.410-win-x64.exe