Родная альтернатива wget в Windows PowerShell?

313962
jsalonen

Я знаю, что могу загрузить и установить вышеупомянутую библиотеку (wget для Windows), но мой вопрос таков:

В Windows PowerShell есть собственная альтернатива wget?

Мне нужно wgetпросто получить файл с заданного URL с помощью HTTP GET. Например:

wget http://www.google.com/ 
255
Смотрите также http://superuser.com/questions/25538/how-to-download-files-from-command-line-in-windows-like-wget-is-doing jiggunjer 8 лет назад 0

9 ответов на вопрос

210
Warren Rumak

Here's a simple PS 3.0 and later one-liner that works and doesn't involve much PS barf:

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

Note that:

  • wget is an alias for Invoke-WebRequest
  • Invoke-WebRequest returns a HtmlWebResponseObject, which contains a lot of useful HTML parsing properties such as Links, Images, Forms, InputFields, etc., but in this case we're just using the raw Content
  • The file contents are stored in memory before writing to disk, making this approach unsuitable for downloading large files
  • On Windows Server Core installations, you'll need to write this as

    wget http://blog.stackexchange.com/ -UseBasicParsing -OutFile out.html 
  • Prior to Sep 20 2014, I suggested

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

    as an answer.  However, this doesn't work in all cases, as the > operator (which is an alias for Out-File) converts the input to Unicode.

If you are using Windows 7, you will need to install version 4 or newer of the Windows Management Framework.

You may find that doing a $ProgressPreference = "silentlyContinue" before Invoke-WebRequest will significantly improve download speed with large files; this variable controls whether the progress UI is rendered.

Теперь это правильный ответ, и я случайно наткнулся на wget, проверяя, установлен ли я на самом деле. Раздражает, что он не может легко получить имя файла (вы должны указать его в перенаправлении вывода), но эта опция имеет лучший интерфейс, чем реальный wget (на мой взгляд), так что это так. Matthew Scharley 10 лет назад 3
Но [Windows 7 поставляется только с PowerShell 2.0] (http://superuser.com/questions/650814), и результатом будет «Термин« Invoke-WebRequest »не распознается как имя командлета, ... ». Peter Mortensen 9 лет назад 13
Powershell 4 доступен для Windows 7 - это часть Windows Management Framework. http://www.microsoft.com/en-us/download/details.aspx?id=40855 Warren Rumak 9 лет назад 0
Справедливое предупреждение: этот метод помещает все содержимое файла в память перед записью его в файл. Это не очень хорошее решение для загрузки больших файлов. im_nullable 9 лет назад 14
@im_nullable, хороший звонок - я добавил это к посту. Warren Rumak 9 лет назад 1
@dezza, что ты имеешь в виду под "кодированием"? Вывод представляет собой захват содержимого, отправленного в теле ответа HTTP GET, будь то двоичные файлы, HTML или что-либо еще, о чем вы просите. Действительно трудно понять, как .py файл может «сломаться», копируя его необработанное содержимое из одного места в другое, если только веб-сервер не возится с ним первым ..... Warren Rumak 9 лет назад 0
@Warren Попробуйте https://bootstrap.pypa.io/get-pip.py с помощью приведенной выше команды и запустите ее с Python 2.7, затем попробуйте другой инструмент, такой как wget, и он будет работать нормально. dezza 9 лет назад 0
@dezza Я обновил ответ с другим подходом. Попробуйте снова. Warren Rumak 9 лет назад 1
@Warren +1 :) лучше и короче. dezza 9 лет назад 0
ps Чтобы сохранить некоторую типизацию, вы можете набрать -o, а затем нажать Tab, чтобы получить завершение табуляции для -OutFile. Warren Rumak 9 лет назад 0
Благодарю. Вы случайно не знаете, как очистить копию / буфер обмена с консоли PS без выбора блока? Это раздражает копирование из PS, потому что почти каждая длинная команда переносится на следующую строку. dezza 9 лет назад 0
Вы можете перенаправить вывод powershell в буфер обмена, выполнив что-то вроде «Get-PSDrive | clip». Просто имейте в виду, что он будет перезаписывать вывод как Unicode. Warren Rumak 9 лет назад 0
Кроме того, консоль в PowerShell ISE не разделяет логику выбора консоли. Я предлагаю использовать это вместо стандартной консоли PS. Warren Rumak 9 лет назад 0
Это не работает, если вы находитесь за аутентификационным межсетевым экраном. Появляется ошибка «Требуется проверка подлинности прокси». Вы можете исправить это, запустив `$ wc = New-Object Net.WebClient; $ wc.UseDefaultCredentials = $ true; $ wc.Proxy.Credentials = $ wc.Credentials`. Кажется, вам нужно делать это только один раз за сеанс. (Я не уверен на 100%, почему это работает, похоже, что прокси-сервер является общим объектом на уровне сеанса ...) Paul Moore 9 лет назад 0
Это использует IE, как и все в Powershell, это было сделано быстро и грязно, а не просто путем интеграции wget или curl. Но очевидно, что если Microsoft сделает это, это разрушит их лицензирование. Chris S 8 лет назад 0
@ChrisS Он не использует IE, если вы указали параметр -UseBasicParsing. (Вот почему этот параметр необходим для Server Core) Warren Rumak 8 лет назад 0
175
Traveling Tech Guy

Если вам просто нужно получить файл, вы можете использовать метод DownloadFile объекта WebClient :

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

Где $urlстрока, представляющая URL-адрес файла и $pathпредставляющая локальный путь, в который будет сохранен файл.

Обратите внимание, что $pathдолжно включать имя файла; это не может быть просто каталог.

До сих пор это было лучшее предлагаемое решение. Также, учитывая, что кажется, что я могу переписать его в формате одной строки как `(new-object System.Net.WebClient) .DownloadFile ('$ url, $ path)`, это лучшее соответствие для `wget`, которое я видел до сих пор. , Спасибо! jsalonen 12 лет назад 28
Как примечание вы также можете сделать это асинхронно, используя что-то вроде (new-object System.Net.WebClient) .DownloadFileAsync (url, filePath) James 11 лет назад 2
Можем ли мы получить определенный текст через Webclient и отправить его в блокнот? Спасибо Mowgli 10 лет назад 0
Да, это работает из коробки в Windows 7 ([поставляется с PowerShell 2.0] (http://superuser.com/questions/650814)). Пример: `$ client.DownloadFile (" http://blog.stackexchange.com/ "," c: /temp2/_Download.html ")` Peter Mortensen 9 лет назад 5
Почему при этом используется 100% одного из моих процессоров? Hut8 8 лет назад 0
@jsalonen и, поскольку это .NET, он работает на PS 2.0, которой я ограничен в данный момент. Nick 7 лет назад 0
Для получения только URL-адреса и игнорирования результатов (например, части сценария разогрева IIS) используйте DownloadData: `(new-object System.Net.WebClient) .DownloadData ($ url) | Из-Null` BurnsBA 7 лет назад 3
Сообщения об ошибках очень бесполезны; если `$ path` является каталогом или существующим файлом, он генерирует общее исключение. Ах, Microsoft. BaseZen 6 лет назад 0
81
user4514

В Invoke-WebRequestследующей версии PowerShell 3:

Invoke-WebRequest http://www.google.com/ -OutFile c:\google.html 
вся элегантность `дд` ... gWaldo 11 лет назад 8
@gWaldo, ты шутишь - это радость для использования (говоря как кто-то, только изучающий PS) Jack Douglas 11 лет назад 1
Я просто имею в виду, что параметр `-Outfile` кажется посторонним, когда вы можете просто использовать`> `(для перезаписи) или` >> `(для добавления) в файл. gWaldo 11 лет назад 8
@gWaldo или даже вывести имя файла из URL, как это делает `wget` :) Peltier 10 лет назад 5
`Invoke-WebRequest $ url ($ url -split" / ") [- 1]`. К сожалению, происходит сбой, если URL заканчивается косой чертой. Должно быть довольно просто улучшить. Peltier 10 лет назад 0
А начиная с PS 4.0, `wget` и` curl` по умолчанию привязаны к `Invoke-WebRequest` (` iwr`): D Bob 10 лет назад 5
@Bob Thx, не стесняйтесь редактировать ответ и включать эти псевдонимы! user4514 10 лет назад 0
@gWaldo PowerShell может быть довольно гладким. Вы можете использовать ярлыки `(iwr http://www.google.com/).Content> google.html` или использовать аргументы` Invoke-WebRequest -Uri "http://www.google.com" -OutFile google.html `. Важно понимать, что в PowerShell канал - это объектный канал, а не просто символьный канал, поэтому вывод `Invoke-WebRequest` - это не поток файла, а скорее объект, для которого вам нужно использовать` .Content `. Попробуйте это: `$ foo = Invoke-WebRequest http: // www.google.com` then` $ foo | Get-Member` затем `$ foo.StatusCode` или` $ foo.Content`. Tyler Szabo 7 лет назад 1
В Windows 2016 Core / Standard мне пришлось пройти `-usebasicparsing`, так как в противном случае он жаловался на отсутствие движка Internet Explorer Adi Roiban 6 лет назад 1
16
Matthew Steeples

Это немного грязно, но есть этот пост в блоге, который дает вам инструкции для загрузки файлов.

В качестве альтернативы (и я рекомендую это) вы можете использовать биты:

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

Он покажет прогресс и загрузит файл в текущий каталог.

BITS полагается на поддержку на стороне сервера, если доступно, это работает в фоновом режиме, и вы можете получать обновления прогресса с другими командлетами. Richard 12 лет назад 2
Я попытался получить http://www.google.com/, но все, что я получил, это `Start-BitsTransfer: доступ запрещен. (Исключение из HRESULT: 0x80070005 (E_ACCESSDENIED)) `. Я озадачен: | jsalonen 12 лет назад 2
@jsalonen Я думаю, что BITS будет загружать только файлы, а не страницы. Как говорит Ричард, он опирается на некоторую поддержку на стороне сервера (хотя я не думаю, что это специфично для Microsoft). Matthew Steeples 12 лет назад 1
Я вижу и думаю, что понимаю смысл использования BITS, однако здесь дело не в том, что я ищу. jsalonen 12 лет назад 0
Мне нужно запомнить это. Спасибо! flickerfly 9 лет назад 0
6
eyecatchUp

PowerShell V4 One-liner:

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

или же

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

Это в основном Уоррен (удивительный) однострочный V3 (спасибо за это!) - с небольшим изменением, чтобы он работал в PowerShell V4.

Однострочник Уоррена - который просто использует, wgetа не iwr- должен все еще работать для V3 (по крайней мере, я думаю, хотя и не проверял его). Тем не мение. Но при попытке выполнить его в PowerShell V4 (как я пытался) вы увидите, что PowerShell не удается преобразовать wgetв действительный командлет / программу.

Для тех, кто заинтересован, это - как я понял из комментария Боба в ответ на принятый ответ (спасибо, мужик!) - потому чтоwgetcurlInvoke-WebRequestiwr начиная с PowerShell V4 и для которого назначены псевдонимы , установлено по умолчанию . Таким образом, wgetне может быть решена (а также curlне может работать здесь) .

4
user25986

Here is a PowerShell function that resolves short URLs before downloading the file

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 } } } 

Use it like this to download the file to the current folder:

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

Or to download the file to a specified folder:

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

The following function will get a 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) } 

Some comments:

  1. The last 4 lines are only needed if you are behind an authenticating proxy. For simple use, (New-Object Net.WebClient).DownloadFile($url, $path) works fine.
  2. The path must be absolute, as the download is not done in your current directory, so relative paths will result in the download getting lost somewhere.
  3. The if (!$path) {...} section handles the simple case where you just want to download the file to the current directory using the name given in the URL.
1
Miloud Eloumri

Используйте оболочку Windows 10 bash, которая включает в себя wget после настройки Windows.

Как установить оболочку Ubuntu Bash на Windows:

YouTube: запуск Bash в Ubuntu под Windows!

Документация по подсистеме Windows для Linux

Подумайте о том, чтобы добавить к этому ответу некоторую цитируемую ссылку, подтверждающую то, что вы заявляете на случай, если ссылка когда-либо умрет, чтобы содержание ответа все еще было доступно, и в настоящее время доступно только по этой ссылке в соответствии с вашим предложением. Pimp Juice IT 6 лет назад 1
-1
zimba

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

Примечание: параметр -outfile ожидает строку, поэтому, если имя вашего файла начинается с цифры и не заключено в кавычки, выходной файл не создается.

Это не влияет на имена файлов, начинающиеся с буквы.

Это решение упоминается в других ответах (wget является псевдонимом Invoke-WebRequest и аналогичен приведенному выше). bertieb 5 лет назад 0
Суть ответа заключалась в том, чтобы подчеркнуть примечание. Ни один из ответов не касается созданного файла из-за синтаксической ошибки. zimba 5 лет назад 0
Это действительно должен быть комментарий к другому ответу [s] bertieb 5 лет назад 0