Questão Alternativa nativa para o wget no Windows PowerShell?


Eu sei que posso baixar e instalar a biblioteca mencionada (wget para Windows), mas minha pergunta é a seguinte:

No Windows PowerShell, existe uma alternativa nativa para wget?

eu preciso wget simplesmente para recuperar um arquivo de um determinado URL com HTTP GET. Por exemplo:

wget http://www.google.com/

244


origem


Veja também superuser.com/questions/25538/… - jiggunjer


Respostas:


Aqui está um simples PS 3.0 e posterior one-liner que funciona e não envolve muito PS barf:

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

Observe que:

  • wget é um alias para Invoke-WebRequest
  • Invoke-WebRequest retorna um HtmlWebResponseObject, que contém muitas propriedades úteis de análise de HTML, como Links, Imagens, Formulários, InputFields, etc., mas neste caso estamos apenas usando o conteúdo bruto
  • O conteúdo do arquivo é armazenado na memória antes de gravar no disco, tornando essa abordagem inadequada para o download de arquivos grandes
  • Nas instalações do Windows Server Core, você precisará escrever isso

    wget http://blog.stackexchange.com/ -UseBasicParsing -OutFile out.html
    
  • Antes de 20 de setembro de 2014, sugeri

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

    como uma resposta. No entanto, isso não funciona em todos os casos, como o > operador (que é um alias para Out-File) converte a entrada para Unicode.

Se você estiver usando o Windows 7, precisará instalar a versão 4 ou mais recente do Windows Management Framework.

Você pode achar que fazer um $ProgressPreference = "silentlyContinue" antes Invoke-WebRequest irá melhorar significativamente a velocidade de download com arquivos grandes; essa variável controla se a interface do usuário de progresso é renderizada.


199



Esta é agora a resposta correta, e eu corri para o wget acidentalmente testando se eu tinha o wget real instalado. Irritante que não pode obter o nome do arquivo facilmente (você tem que especificá-lo no redirecionamento de saída), mas essa opção tem uma interface do usuário melhor do que o real wget (na minha opinião), então não é isso. - Matthew Scharley
Mas O Windows 7 só vem com o PowerShell 2.0, e o resultado será "O termo 'Invoke-WebRequest' não é reconhecido como o nome de um cmdlet, ...". - Peter Mortensen
Aviso justo: este método colocará todo o conteúdo do arquivo na memória antes de gravá-lo no arquivo. Esta não é uma boa solução para baixar arquivos grandes. - im_nullable
@im_nullable, boa ligação - adicionei isso ao post. - Warren Rumak
@dezza atualizei a resposta com uma abordagem diferente. Tente de novo. - Warren Rumak


Se você só precisa recuperar um arquivo, você pode usar o ⇬ Fazer download do arquivo método do Cliente da web objeto:

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

Onde $url é uma string representando o URL do arquivo e $path está representando o caminho local para o qual o arquivo será salvo.

Observe que $path deve incluir o nome do arquivo; Não pode ser apenas um diretório.


169



Até agora esta foi a melhor solução proposta. Além disso, dado que parece que eu posso reescrevê-lo em um formato de linha como (new-object System.Net.WebClient).DownloadFile( '$url, $path) é a melhor correspondência para wget Eu vi até agora. Obrigado! - jsalonen
Como uma nota lateral, você também pode fazer isso de forma assíncrona usando algo como (new-object System.Net.WebClient) .DownloadFileAsync (url, filePath) - James
Podemos buscar um texto em particular via Webclient e sair para um bloco de notas? obrigado - Mowgli
Sim, isso funciona fora da caixa no Windows 7 (que vem com o PowerShell 2.0). Amostra: $client.DownloadFile( "http://blog.stackexchange.com/", "c:/temp2/_Download.html") - Peter Mortensen
Por apenas obter um URL e ignorar os resultados (por exemplo, parte de um script de aquecimento do IIS) use DownloadData: (new-object System.Net.WebClient).DownloadData($url) | Out-Null - BurnsBA


Há sim Invoke-WebRequest na próxima versão 3 do PowerShell:

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

81



toda a elegância de dd... - gWaldo
@gWaldo você está brincando - isso é uma alegria para usar (falando como alguém apenas aprendendo PS) - Jack Douglas
Eu só quero dizer que o -Outfile parâmetro parece estranho quando você poderia simplesmente usar > (para sobrescrever) ou >> (para acrescentar) a um arquivo. - gWaldo
@gWaldo ou mesmo deduzir o nome do arquivo da URL como wget faz :) - Peltier
E a partir do PS 4.0, wget e curl são aliasted para Invoke-WebRequest (iwr) por padrão: D - Bob


É um pouco confuso, mas existe este post de blog que lhe dá instruções para baixar arquivos.

Alternativamente (e este é um que eu recomendo) você pode usar o BITS:

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

Ele mostrará o progresso e fará o download do arquivo para o diretório atual.


16



O BITS depende do suporte no servidor, se disponível, isso funciona em segundo plano e você pode obter atualizações de progresso com outros cmdlets. - Richard
Eu tentei buscar google.com, mas tudo que eu tenho é Start-BitsTransfer : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)). Estou intrigado: | - jsalonen
@jsalonen Acho que o BITS só baixará arquivos em vez de páginas. Como Richard diz que depende de algum suporte do lado do servidor (embora eu não acho que é específico da Microsoft). - Matthew Steeples
Eu vejo e acho que entendi o ponto de usar o BITS, no entanto, não é o que estou procurando aqui. - jsalonen
Eu preciso me lembrar disso. Obrigado! - flickerfly


PowerShell V4 One-liner:

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

ou

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

Isso é basicamente Warren (impressionante) V3 one-liner  (obrigado por isso!) - com apenas uma pequena alteração, a fim de fazê-lo funcionar em um PowerShell V4.

O one-liner de Warren - que simplesmente usa wget ao invés de iwr - ainda deve trabalhar para V3 (Pelo menos, eu acho; não testei, no entanto). De qualquer forma. Mas ao tentar executá-lo em um V4 PowerShell (como tentei), você verá o PowerShell não conseguir resolver wget como um cmdlet / programa válido.

Para aqueles interessados, isto é - como eu peguei de Comentário de Bob em resposta a a resposta aceita  (obrigado, cara!) - Porque a partir do PowerShell V4, wget e curl são aliased para Invoke-WebRequest, definido como iwr por padrão. Portanto, wgetnão pode ser resolvido (assim como curl não pode trabalhar aqui).


6





Aqui está uma função do PowerShell que resolve URLs curtos antes de baixar o arquivo

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-o assim para baixar o arquivo para a pasta atual:

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

Ou para baixar o arquivo para uma pasta especificada:

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

4





A seguinte função irá obter um 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)
}

Alguns comentários:

  1. As últimas 4 linhas são necessárias apenas se você estiver atrás de um proxy de autenticação. Para uso simples, (New-Object Net.WebClient).DownloadFile($url, $path) funciona bem.
  2. O caminho devo ser absoluto, como o download não é feito em seu diretório atual, então caminhos relativos resultarão no download sendo perdido em algum lugar.
  3. o if (!$path) {...} seção manipula o caso simples, onde você só quer baixar o arquivo para o diretório atual usando o nome dado no URL.

2