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


283

Я знаю, що можу завантажити та встановити формовану бібліотеку (wget для Windows), але моє запитання таке:

Чи є в Windows PowerShell рідна альтернатива wget?

Мені wgetпросто потрібно завантажити файл із заданої URL-адреси за допомогою HTTP GET. Наприклад:

wget http://www.google.com/

Дивіться також superuser.com/questions/25538/…
jiggunjer

Відповіді:


236

Ось простий PS 3.0 і пізніший однокласник, який працює і не залучає багато PS Barf:

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

Зауважте, що:

  • wget псевдонім для Invoke-WebRequest
  • Invoke-WebRequest повертає HtmlWebResponseObject , який містить багато корисних властивостей для розбору HTML, таких як Посилання, Зображення, Форми, Вхідні поля тощо, але в цьому випадку ми просто використовуємо необроблений вміст
  • Вміст файлу зберігається в пам'яті перед записом на диск, що робить цей підхід непридатним для завантаження великих файлів
  • На установках Windows Server Core вам потрібно буде записати це як

    wget http://blog.stackexchange.com/ -UseBasicParsing -OutFile out.html
    
  • До 20 вересня 2014 року я запропонував

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

    як відповідь. Однак це не працює у всіх випадках, оскільки >оператор (який є псевдонімом Out-File) перетворює вхід на Unicode.

Якщо ви використовуєте Windows 7, вам потрібно буде встановити версію 4 або новішу версію Windows Management Framework.

Ви можете виявити, що виконання $ProgressPreference = "silentlyContinue"раніше Invoke-WebRequestзначно покращить швидкість завантаження великих файлів; ця змінна контролює, чи надається інтерфейс прогресу.


3
Тепер це правильна відповідь, і я зіткнувся з wget випадково тестуючи, чи був у мене встановлений фактичний wget. Дратує, що він не може легко отримати ім'я файлу (ви повинні вказати його у перенаправлення виводу), але цей параметр має кращий інтерфейс, ніж реальний wget (на мою думку), так що це є.
Меттью Шарлі

13
Але Windows 7 поставляється лише з PowerShell 2.0 , і результатом буде "Термін" Invoke-WebRequest "не визнається назвою командлета, ...".
Пітер Мортенсен

16
Справедливе попередження: Цей метод дозволить зберегти весь вміст файлу в пам'яті перед тим, як записати його у файл. Це не гарне рішення для завантаження великих файлів.
im_nullable

2
@im_nullable, хороший дзвінок - я додав це до посади.
Warren Rumak

1
@dezza Я оновив відповідь іншим підходом. Спробуйте ще раз.
Воррен Румак

181

Якщо вам потрібно просто завантажити файл, ви можете використовувати метод DownloadFile об’єкта WebClient :

$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
Як побічний відзначити , ви також можете зробити це асинхронно , використовуючи що - щось на зразок (новий об'єкт System.Net.WebClient) .DownloadFileAsync (URL, Filepath)
Джеймс

Чи можемо ми отримати певний текст через Webclient і вивести його в блокнот? дякую
Мауглі

6
Так, це працює у вікні Windows 7 ( що постачається з PowerShell 2.0 ). Зразок: $client.DownloadFile( "http://blog.stackexchange.com/", "c:/temp2/_Download.html")
Пітер Мортенсен

3
Для отримання лише URL-адреси та ігнорування результатів (наприклад, частини сценарію розминки IIS) використовуйте DownloadData:(new-object System.Net.WebClient).DownloadData($url) | Out-Null
BurnsBA

86

Є Invoke-WebRequestв майбутній версії PowerShell 3:

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

9
вся витонченість dd...
gWaldo

1
@gWaldo ви жартуєте - це радість використовувати (говорити як хтось, хто тільки вивчає PS)
Джек Дуглас

8
Я маю на увазі, що -Outfileпараметр здається стороннім, коли ви можете просто використовувати >(перезаписати) або >>(додати) файл.
gWaldo

5
@gWaldo або навіть вивести ім'я файлу з URL-адреси, як wgetце робиться :)
Peltier

5
А станом на PS 4.0, wgetі за замовчуванням curlїх псевдоніми до Invoke-WebRequest( iwr): D
Боб

18

Це трохи безладно, але є цей пост у блозі, який дає вам інструкції щодо завантаження файлів.

Як варіант (і це я рекомендую), ви можете використовувати BITS:

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

Він покаже прогрес і завантажить файл у поточний каталог.


3
BITS розраховує на підтримку на кінці сервера, якщо вона доступна, це працює у фоновому режимі, і ви можете отримувати оновлення прогресу з іншими командлетами.
Річард

2
Я намагався знайти google.com , але все, що я отримую, - це Start-BitsTransfer : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)). Я спантеличений: |
jsalonen

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як дійсний командлет / програма.

Для тих, хто цікавиться, це - як я взяв із коментаря Боба у відповідь на прийняту відповідь (спасибі, чоловіче!) - тому що PowerShell V4, wgetі для curlнього чужий Invoke-WebRequest, встановлений iwrза замовчуванням . Таким чином, 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-адресі.

1

Використовуйте оболонку Windows 10 bash, яка включає wget, коли налаштування функції Windows.

Як встановити оболонку bash Ubuntu в Windows:

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

Підсистема Windows для документування Linux


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

0

Якщо ваша Windows досить нова (наприклад, версія 1809 або новіша версія), наявна "справжня" завитка. curl має параметр командного рядка "-O" (велика літера O; мала літера не буде робити те саме!) Опція "-O", альтернативно "-remote-name" повідомляє curl, що збережений файл отримує те саме ім’я, що і назва файлу в URL-адресі.

Потрібно запустити це як "curl.exe", щоб відрізнити його від псевдоніму "curl" для "Invoke-WebRequest". Між іншим, він працює в cmd.exe без змін.

Використовуючи той же приклад, що і в іншій відповіді тут

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

(Сайт не дозволить мені додати це як коментар, оскільки я, мабуть, потребую більшої "репутації" для цього - тому він отримує нову відповідь)


0

Invoke-WebRequest з параметром -outfile очікує рядок, тому якщо ваше ім'я файлу починається з числа, а не вкладається в лапки, вихідний файл не створюється.

напр. Invoke-WebRequest -Uri "http://www.google.com/" -outfile "2.pdf"

Це не впливає на назви файлів, починаючи з літери.


Це рішення згадується в інших відповідях ( wgetє псевдонімом Invoke-WebRequestі подібним до вище)
bertieb

Суть відповіді полягала в тому, щоб підкреслити ноту. Жодна з відповідей не стосується створення файлу через помилку синтаксису.
Зімба

Це дійсно має бути коментар до іншої відповіді
bertieb

Ця відповідь не надана в інших відповідях, ні аналогічна вище.
Зімба

-1

Це повинно допомогти вам обійти відсутні матеріали, ініціалізовані браузером. Зверніть увагу на параметр "-UseBasicParsing".

Invoke-WebRequest http://localhost -UseBasicParsing

(1) Що таке "речі, не ініціалізовані браузером"? (2) Зауважте, що прийнята відповідь вже згадується -UseBasicParsing.
Скотт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.