題 Windows PowerShell中wget的本機替代?


我知道我可以下載並安裝上述庫(wget for Windows),但我的問題是:

在Windows PowerShell中,是否存在本機替代方案 wget

我需要 wget 只需使用HTTP GET從給定的URL檢索文件。例如:

wget http://www.google.com/

253
2017-11-28 09:56


起源


也可以看看 superuser.com/questions/25538/... - jiggunjer


答案:


這是一個簡單的PS 3.0和後來的單線程,可以工作,並且不涉及太多的PS barf:

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

注意:

  • wget 是別名 Invoke-WebRequest
  • Invoke-WebRequest返回一個 HtmlWebResponseObject,它包含許多有用的HTML解析屬性,如鍊接,圖像,表單,InputFields等,但在這種情況下,我們只是使用原始內容
  • 在寫入磁盤之前,文件內容存儲在內存中,使得此方法不適合下載大文件
  • 在Windows Server Core安裝中,您需要將其編寫為

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

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

    作為答案。但是,這在所有情況下都不起作用 > operator(是別名) Out-File)將輸入轉換為Unicode。

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

你可能會發現做了一個 $ProgressPreference = "silentlyContinue" 之前 Invoke-WebRequest 將大大提高大文件的下載速度;此變量控制是否呈現進度UI。


207
2017-12-26 06:47



現在這是正確的答案,我遇到了wget意外測試我是否安裝了實際的wget。令人煩惱的是它無法輕鬆獲取文件名(你必須在輸出重定向中指定它),但是這個選項有比真實wget更好的UI(在我看來)所以就是這樣。 - Matthew Scharley
但 Windows 7僅附帶PowerShell 2.0,結果將是“術語'Invoke-WebRequest'不被識別為cmdlet的名稱,......”。 - Peter Mortensen
公平警告:此方法會在將文件寫入文件之前將文件的全部內容放入內存。這不是下載大文件的好方法。 - im_nullable
@im_nullable,好的電話 - 我已經把它添加到帖子中。 - Warren Rumak
@dezza我用不同的方法更新了答案。再試一遍。 - Warren Rumak


如果您只需要檢索文件,則可以使用 下載文件 的方法 Web客戶端 賓語:

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

哪裡 $url 是表示文件URL的字符串,和 $path 表示文件將保存到的本地路徑。

注意 $path 必須包含文件名;它不能只是一個目錄。


175
2017-11-28 10:20



到目前為止,這是提出的最佳解決方案。另外考慮到我似乎可以用一種格式重寫它 (new-object System.Net.WebClient).DownloadFile( '$url, $path) 這是最好的對應 wget 到目前為止我見過。謝謝! - jsalonen
作為附註,您也可以使用類似(new-object System.Net.WebClient)的內容異步執行此操作.DownloadFileAsync(url,filePath) - James
我們可以通過Webclient獲取特定文本並輸出到記事本嗎?謝謝 - Mowgli
是的,這在Windows 7上開箱即用(隨PowerShell 2.0一起提供)。樣品: $client.DownloadFile( "http://blog.stackexchange.com/", "c:/temp2/_Download.html") - Peter Mortensen
只是獲取一個URL並忽略結果(例如,IIS預熱腳本的一部分)使用DownloadData: (new-object System.Net.WebClient).DownloadData($url) | Out-Null - BurnsBA


Invoke-WebRequest 在即將推出的PowerShell版本3中:

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

81
2017-08-10 23:38



所有的優雅 dd... - gWaldo
@gWaldo你在開玩笑 - 這是一種使用的快樂(作為一個剛剛學習PS的人說話) - Jack Douglas
我的意思是 -Outfile 當你可以使用時,參數似乎無關緊要 > (覆蓋)或 >> (附加)到文件。 - gWaldo
@gWaldo甚至可以從URL中推斷出文件名 wget :) - Peltier
從PS 4.0開始, wget 和 curl 被別名 Invoke-WebRequest (iwr)默認情況下:D - Bob


它有點亂,但有 這篇博文 它為您提供下載文件的說明。

或者(這是我推薦的)您可以使用BITS:

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

它將顯示進度並將文件下載到當前目錄。


16
2017-11-28 10:18



BITS依賴於服務器端的支持,如果可用,它在後台運行,您可以使用其他cmdlet獲取進度更新。 - Richard
我試著去取 google.com,但我得到的只是 Start-BitsTransfer : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))。我很困惑:| - jsalonen
@jsalonen我認為BITS只會下載文件而不是頁面。正如理查德所說,它依賴於服務器端的一些支持(儘管我不認為它是微軟特有的)。 - Matthew Steeples
我看到並且我認為我明白了使用BITS,但是,它不是我在這裡尋找的東西。 - jsalonen
我需要記住那個。謝謝! - flickerfly


PowerShell V4 One-liner:

(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 /程序。

對於那些感興趣的人,就是 - 就像我從中撿到的那樣 鮑勃的評論 在回复 接受的答案  (謝啦!)  - 因為 從PowerShell V4開始, wget 和 curl 別名 Invoke-WebRequest, 調成 iwr 默認情況下。從而, wget無法解決 (以及 curl 不能在這里工作)


6
2018-05-25 10:22





這是一個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  

4
2017-08-12 10:48





以下函數將獲取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) {...} section處理簡單的情況,你只想使用URL中給出的名稱將文件下載到當前目錄。

2
2017-12-15 15:26