Windows PowerShell中wget的本机替代品?


Answers:


236

这是一个简单的PS 3.0和更高版本的单行代码,其工作原理并不涉及太多的PS barf:

wget http://blog.stackexchange.com/ -OutFile out.html

注意:

  • wget 是的别名 Invoke-WebRequest
  • Invoke-WebRequest返回一个HtmlWebResponseObject,其中包含许多有用的HTML解析属性,例如Links,Images,Forms,InputFields等,但是在这种情况下,我们仅使用原始Content
  • 文件内容在写入磁盘之前先存储在内存中,这使该方法不适合下载大文件
  • 在Windows Server Core安装中,您需要将其写为

    wget http://blog.stackexchange.com/ -UseBasicParsing -OutFile out.html
    
  • 在2014年9月20日之前,我建议

    (wget http://blog.stackexchange.com/).Content >out.html
    

    作为答案。但是,这并非在所有情况下都可行,因为>运算符(是的别名Out-File)会将输入转换为Unicode。

如果您使用的是Windows 7,则需要安装Windows Management Framework的版本4或更高版本。

您可能会发现,使用$ProgressPreference = "silentlyContinue"before Invoke-WebRequest可以大大提高大文件的下载速度。此变量控制是否呈现进度UI。


3
现在这是正确的答案,我遇到wget意外地测试了是否安装了实际的wget。令人烦恼的是它无法轻松获取文件名(您必须在输出重定向中指定它),但是此选项具有比真实wget更好的UI(我认为),因此就可以了。
Matthew Scharley 2014年

13
但是Windows 7仅随PowerShell 2.0一起提供,结果将是“术语'Invoke-WebRequest'未被识别为cmdlet的名称,...”。
Peter Mortensen 2014年

16
合理警告:此方法会将文件的全部内容放入内存中,然后再将其写出到文件中。这不是下载大文件的好方法。
im_nullable 2014年

2
@im_nullable,打个招呼-我已将其添加到帖子中。
沃伦·鲁马克

1
@dezza我用另一种方法更新了答案。再试一遍。
沃伦·鲁马克

181

如果只需要检索文件,则可以使用WebClient对象的DownloadFile方法:

$client = New-Object System.Net.WebClient
$client.DownloadFile($url, $path)

其中$url是代表文件URL的字符串,代表$path文件将被保存到的本地路径。

注意,$path必须包含文件名;它不能只是一个目录。


32
到目前为止,这是提出的最佳解决方案。还考虑到我似乎可以用一种行格式重写它,因为(new-object System.Net.WebClient).DownloadFile( '$url, $path)这是wget到目前为止我所看到的最好的对应关系。谢谢!
jsalonen

3
作为一个旁注,您还可以使用(new-object System.Net.WebClient).DownloadFileAsync(url,filePath)
James

我们可以通过Webclient提取特定文本并将其发送到记事本吗?谢谢
Mowgli 2013年

6
是的,这可以在Windows 7(PowerShell 2.0附带)上直接使用。范例: $client.DownloadFile( "http://blog.stackexchange.com/", "c:/temp2/_Download.html")
Peter Mortensen 2014年

3
对于仅获取URL并忽略结果(例如,IIS预热脚本的一部分),请使用DownloadData:(new-object System.Net.WebClient).DownloadData($url) | Out-Null
BurnsBA '17

86

Invoke-WebRequest在即将到来的PowerShell版本3:

Invoke-WebRequest http://www.google.com/ -OutFile c:\google.html

9
所有的优雅dd……
gWaldo

1
@gWaldo,您在开玩笑–使用起来很有趣(就像刚学习PS的人一样)
Jack Douglas

8
我只是说,-Outfile当您可以仅使用>(覆盖)或>>(附加)到文件时,该参数似乎无关紧要。
gWaldo 2012年

5
@gWaldo甚至从URL推断出文件名,就像这样wget做:)
Peltier

5
而作为PS 4.0,wgetcurl被aliasted到Invoke-WebRequestiwr默认):d
鲍勃

18

有点混乱,但是此博客文章为您提供了下载文件的说明。

另外(我建议您这样做),您可以使用BITS:

Import-Module BitsTransfer
Start-BitsTransfer -source "http://urlToDownload"

它将显示进度,并将文件下载到当前目录。


3
BITS依靠服务器端的支持(如果可用)在后台运行,并且您可以使用其他cmdlet获得进度更新。
理查德

2
我试图获取google.com,但得到的只是Start-BitsTransfer : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))。我很困惑:|
jsalonen 2011年

1
@jsalonen我认为BITS只会下载文件而不是页面。正如理查德所说,它依赖于某些服务器端支持(尽管我认为这不是特定于Microsoft的)。
马修·斯蒂夫斯

我看到了,我想我知道使用BITS的意义,但是,这不是我在这里想要的。
jsalonen

6

PowerShell V4一线式:

(iwr http://blog.stackexchange.com/).Content >index.html`

要么

(iwr http://demo.mediacore.tv/files/31266.mp4).Content >video.mp4

基本上,这是沃伦的(很棒的)V3单行代码 (感谢!) -进行了微小的更改,以使其能够在V4 PowerShell中使用。

沃伦的单线 -仅使用wget而不是iwr-仍应适用于V3(至少,我想;不过并未进行测试)。无论如何。但是,当尝试在V4 PowerShell中执行它时(如我所试),您将看到PowerShell无法解析wget为有效的cmdlet /程序。

对于那些感兴趣的人,这是-正如我从Bob的评论中回答接受的答案 (谢谢,伙计!)一样 -因为从PowerShell V4开始,wget并且curl别名为Invoke-WebRequestiwr默认设置为。因此,wget无法解决(以及curl无法在此处工作)


4

这是一个PowerShell函数,可在下载文件之前解析短URL

function Get-FileFromUri {  
    param(  
        [parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
        [string]
        [Alias('Uri')]
        $Url,
        [parameter(Mandatory=$false, Position=1)]
        [string]
        [Alias('Folder')]
        $FolderPath
    )
    process {
        try {
            # resolve short URLs
            $req = [System.Net.HttpWebRequest]::Create($Url)
            $req.Method = "HEAD"
            $response = $req.GetResponse()
            $fUri = $response.ResponseUri
            $filename = [System.IO.Path]::GetFileName($fUri.LocalPath);
            $response.Close()
            # download file
            $destination = (Get-Item -Path ".\" -Verbose).FullName
            if ($FolderPath) { $destination = $FolderPath }
            if ($destination.EndsWith('\')) {
                $destination += $filename
            } else {
                $destination += '\' + $filename
            }
            $webclient = New-Object System.Net.webclient
            $webclient.downloadfile($fUri.AbsoluteUri, $destination)
            write-host -ForegroundColor DarkGreen "downloaded '$($fUri.AbsoluteUri)' to '$($destination)'"
        } catch {
            write-host -ForegroundColor DarkRed $_.Exception.Message
        }  
    }  
}  

像这样使用它可以将文件下载到当前文件夹:

Get-FileFromUri http://example.com/url/of/example/file  

或将文件下载到指定的文件夹:

Get-FileFromUri http://example.com/url/of/example/file  C:\example-folder  

2

以下函数将获取一个URL。

function Get-URLContent ($url, $path) {
  if (!$path) {
      $path = Join-Path $pwd.Path ([URI]$url).Segments[-1]
  }
  $wc = New-Object Net.WebClient
  $wc.UseDefaultCredentials = $true
  $wc.Proxy.Credentials = $wc.Credentials
  $wc.DownloadFile($url, $path)
}

一些评论:

  1. 仅当您在身份验证代理后面时才需要最后4行。对于简单的使用,(New-Object Net.WebClient).DownloadFile($url, $path)效果很好。
  2. 该路径必须是绝对路径,因为下载未在当前目录中完成,因此相对路径将导致下载在某处丢失。
  3. if (!$path) {...}节处理的简单情况是,您只想使用URL中提供的名称将文件下载到当前目录。


0

如果您的Windows足够新(例如1809版或更高版本),则可以使用“真正的”卷曲。curl具有命令行选项“ -O”(大写字母O;小写字母也不会这样做!)选项“ -O”或“ --remote-name”告诉curl,保存的文件将获得与URL的文件名部分相同的名称。

需要以“ curl.exe”启动它,以与“ Invoke-WebRequest”的别名“ curl”相区别。顺便说一句,它无需更改即可在cmd.exe中工作。

使用与此处另一个答案相同的示例

curl.exe -O http://demo.mediacore.tv/files/31266.mp4

(该站点不允许我将其添加为评论,因为我显然为此需要更多的“声誉”-因此它得到了一个新的答案)


0

带有-outfile参数的Invoke-WebRequest需要一个字符串,因此,如果您的文件名以数字开头且未用引号引起来,则不会创建任何输出文件。

例如。 Invoke-WebRequest -Uri "http://www.google.com/" -outfile "2.pdf"

这不会影响以字母开头的文件名。


此解决方案在其他答案中提到(wget是的别名Invoke-WebRequest,并且与上面的类似)
bertieb

答案的重点是强调注释。由于语法错误,所有答案均未涉及未创建任何文件的问题。
津巴(Zimba)

那真的应该是对其他答案的评论
bertieb

此答案未在其他答案中提供,也未与上述答案类似。
Zimba

-1

这应该可以解决没有浏览器初始化的问题。请注意“ -UseBasicParsing”参数。

Invoke-WebRequest http://localhost -UseBasicParsing

(1)什么是“没有浏览器初始化的东西”?(2)请注意,已接受的答案已提及-UseBasicParsing
斯科特
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.