Thay thế gốc cho wget trong Windows PowerShell?


284

Tôi biết tôi có thể tải xuống và cài đặt thư viện đã nói ở trên (wget cho Windows), nhưng câu hỏi của tôi là:

Trong Windows PowerShell, có một sự thay thế riêng wgetnào không?

Tôi wgetchỉ cần lấy một tệp từ một URL đã cho bằng HTTP GET. Ví dụ:

wget http://www.google.com/

Câu trả lời:


237

Đây là một PS 3.0 đơn giản và một lớp lót mới hơn hoạt động và không liên quan đến nhiều PS barf:

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

Lưu ý rằng:

  • wget là bí danh cho Invoke-WebRequest
  • Invoke-WebRequest trả về một HtmlWebResponseObject , chứa nhiều thuộc tính phân tích cú pháp HTML hữu ích như Liên kết, Hình ảnh, Biểu mẫu, InputField, v.v., nhưng trong trường hợp này, chúng tôi chỉ sử dụng Nội dung thô
  • Nội dung tệp được lưu trữ trong bộ nhớ trước khi ghi vào đĩa, khiến cách tiếp cận này không phù hợp để tải xuống các tệp lớn
  • Trên các bản cài đặt Windows Server Core, bạn sẽ cần phải viết cái này như

    wget http://blog.stackexchange.com/ -UseBasicParsing -OutFile out.html
    
  • Trước ngày 20 tháng 9 năm 2014, tôi đã đề xuất

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

    như một câu trả lời Tuy nhiên, điều này không hoạt động trong mọi trường hợp, vì >toán tử (là bí danh cho Out-File) chuyển đổi đầu vào thành Unicode.

Nếu bạn đang sử dụng Windows 7, bạn sẽ cần cài đặt phiên bản 4 hoặc mới hơn của Khung quản lý Windows.

Bạn có thể thấy rằng làm $ProgressPreference = "silentlyContinue"trước đó Invoke-WebRequestsẽ cải thiện đáng kể tốc độ tải xuống với các tệp lớn; biến này kiểm soát xem UI tiến trình được hiển thị.


3
Bây giờ đây là câu trả lời chính xác và tôi đã vô tình kiểm tra wget nếu tôi đã cài đặt wget thực tế. Khó chịu là nó không thể có được tên tệp một cách dễ dàng (bạn phải chỉ định nó trong chuyển hướng đầu ra), nhưng tùy chọn này có giao diện người dùng tốt hơn so với wget thực (theo ý kiến ​​của tôi) vì vậy có.
Matthew Scharley

13
Nhưng Windows 7 chỉ đi kèm với PowerShell 2.0 và kết quả sẽ là "Thuật ngữ 'Invoke-WebRequest' không được công nhận là tên của một lệnh ghép ngắn, ...".
Peter Mortensen

16
Cảnh báo công bằng: Phương pháp này sẽ đưa toàn bộ nội dung của tệp vào bộ nhớ trước khi ghi ra tệp. Đây không phải là một giải pháp tốt để tải xuống các tệp lớn.
tin được vào

2
@im_nullable, cuộc gọi tốt - Tôi đã thêm nó vào bài viết.
Warren Rumak

1
@dezza Tôi đã cập nhật câu trả lời bằng một cách tiếp cận khác. Thử lại lần nữa.
Warren Rumak

181

Nếu bạn chỉ cần truy xuất một tệp, bạn có thể sử dụng phương thức DownloadFile của đối tượng WebClient :

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

Trường hợp $urlmột chuỗi đại diện cho URL của tệp và $pathđại diện cho đường dẫn cục bộ mà tệp sẽ được lưu vào.

Lưu ý rằng $pathphải bao gồm tên tệp; nó không thể là một thư mục


32
Cho đến nay đây là giải pháp tốt nhất được đề xuất. Cũng cho rằng dường như tôi có thể viết lại nó ở định dạng một dòng vì (new-object System.Net.WebClient).DownloadFile( '$url, $path)nó là sự tương ứng tốt nhất cho wgetđến nay tôi đã thấy. Cảm ơn!
jsalonen

3
Là một lưu ý phụ, bạn cũng có thể thực hiện việc này một cách không đồng bộ bằng cách sử dụng một cái gì đó như (new-object System.Net.WebClient) .DoadFileAsync (url, filePath)
James

Chúng tôi có thể tìm nạp một văn bản cụ thể qua Webclient và outout vào notepad không? cảm ơn
Mowgli

6
Có, tính năng này hoạt động tốt trên Windows 7 ( đi kèm với PowerShell 2.0 ). Mẫu: $client.DownloadFile( "http://blog.stackexchange.com/", "c:/temp2/_Download.html")
Peter Mortensen

3
Để chỉ nhận một url và bỏ qua kết quả (ví dụ: một phần của tập lệnh khởi động IIS), hãy sử dụng DownloadData:(new-object System.Net.WebClient).DownloadData($url) | Out-Null
BurnsBA

86

Invoke-WebRequesttrong phiên bản PowerShell 3 sắp tới:

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

9
tất cả sự tao nhã của dd...
gWaldo

1
@gWaldo bạn đang đùa giỡn, đây là một niềm vui để sử dụng (nói như một người vừa học PS)
Jack Douglas

8
Tôi chỉ có nghĩa là -Outfiletham số có vẻ không liên quan khi bạn chỉ có thể sử dụng >(để ghi đè) hoặc >>(để chắp thêm) vào một tệp.
gWaldo

5
@gWaldo hoặc thậm chí suy ra tên tệp từ URL giống như wgetvậy :)
Peltier

5
Và kể từ PS 4.0, wgetcurlđược mặc định là Invoke-WebRequest( iwr) theo mặc định: D
Bob

18

Hơi lộn xộn một chút nhưng có bài đăng trên blog này cung cấp cho bạn hướng dẫn tải tệp.

Ngoài ra (và đây là một điều tôi muốn giới thiệu) bạn có thể sử dụng BITS:

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

Nó sẽ hiển thị tiến trình và sẽ tải tập tin vào thư mục hiện tại.


3
BITS dựa vào hỗ trợ ở cuối máy chủ, nếu có sẵn thì nó hoạt động ở chế độ nền và bạn có thể nhận được các bản cập nhật tiến độ với các lệnh ghép ngắn khác.
Richard

2
Tôi đã cố gắng tìm nạp google.com , nhưng tất cả những gì tôi nhận được là Start-BitsTransfer : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)). Tôi hoang mang: |
jsalonen

1
@jsalonen Tôi nghĩ rằng BITS sẽ chỉ tải xuống các tệp chứ không phải các trang. Như Richard nói rằng nó phụ thuộc vào một số hỗ trợ phía máy chủ (mặc dù tôi không nghĩ đó là Microsoft cụ thể).
Matthew Steeples

Tôi thấy và tôi nghĩ rằng tôi có điểm khi sử dụng BITS, tuy nhiên, đó không phải là điều tôi đang tìm kiếm ở đây.
jsalonen

6

PowerShell V4 Một lớp lót:

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

hoặc là

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

Về cơ bản, đây là một lớp lót V3 (tuyệt vời) của Warren (cảm ơn vì điều này!) - chỉ với một thay đổi nhỏ để làm cho nó hoạt động trong V4 PowerShell.

Một lớp lót của Warren - chỉ đơn giản là sử dụng wgetchứ không phải iwr- vẫn hoạt động cho V3 (Ít nhất, tôi đoán vậy, mặc dù đã không thử nghiệm nó). Dù sao. Nhưng khi thử thực thi nó trong V4 PowerShell (như tôi đã thử), bạn sẽ thấy PowerShell không giải quyết được wgetnhư một lệnh ghép ngắn / chương trình hợp lệ.

Đối với những người quan tâm, đó là - như tôi nhặt từ bình luận của Bob trả lời các câu trả lời được chấp nhận (cảm ơn, người đàn ông!) - vì như của PowerShell V4, wgetcurlđược lấy bí danh là Invoke-WebRequest, thiết lập để iwrtheo mặc định . Do đó, wgetkhông thể được giải quyết (cũng như curlkhông thể làm việc ở đây) .


4

Đây là chức năng PowerShell giải quyết các URL ngắn trước khi tải xuống tệp

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

Sử dụng nó như thế này để tải tập tin vào thư mục hiện tại:

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

Hoặc để tải tệp xuống một thư mục được chỉ định:

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

2

Các chức năng sau đây sẽ nhận được một 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)
}

Một vài bình luận:

  1. 4 dòng cuối cùng chỉ cần thiết nếu bạn đứng sau một proxy xác thực. Để sử dụng đơn giản, (New-Object Net.WebClient).DownloadFile($url, $path)hoạt động tốt.
  2. Đường dẫn phải tuyệt đối, vì việc tải xuống không được thực hiện trong thư mục hiện tại của bạn, vì vậy các đường dẫn tương đối sẽ dẫn đến việc tải xuống bị mất ở đâu đó.
  3. Phần if (!$path) {...}này xử lý trường hợp đơn giản trong đó bạn chỉ muốn tải tệp xuống thư mục hiện tại bằng cách sử dụng tên được cung cấp trong URL.

1

Sử dụng Windows bash shell bao gồm wget sau khi tính năng windows được thiết lập.

Cách cài đặt Ubuntu bash shell trên Windows:

YouTube: Chạy Bash trên Ubuntu trên Windows!

Hệ thống con Windows cho Tài liệu Linux


1
Xem xét thêm một số tham chiếu được trích dẫn vào câu trả lời này để hỗ trợ những gì bạn nêu trong trường hợp liên kết bị chết vì vậy nội dung câu trả lời vẫn có sẵn mà hiện chỉ có sẵn thông qua liên kết đó theo đề xuất của bạn.
Pimp Juice IT

0

Nếu Windows của bạn đủ mới (như phiên bản 1809 hoặc mới hơn), sẽ có một bản curl "thực". curl có tùy chọn dòng lệnh "-O" (chữ in hoa O; chữ nhỏ sẽ không làm như vậy!) Tùy chọn "-O", thay vào đó "--remote-name" cho curl, rằng tệp đã lưu nhận được cùng tên với phần tên tệp của URL.

Người ta cần bắt đầu điều này là "curl.exe", để phân biệt nó từ "Curl" bí danh cho "Invoke-WebRequest". Ngẫu nhiên nó hoạt động trong cmd.exe mà không thay đổi.

Sử dụng ví dụ tương tự như trong câu trả lời khác ở đây

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

(Trang web sẽ không cho phép tôi thêm nhận xét này vì tôi nhận thấy cần thêm "danh tiếng" cho điều đó - vì vậy nó nhận được câu trả lời mới)


0

Invoke-WebRequest với tham số -outfile mong đợi một chuỗi, vì vậy nếu tên tệp của bạn bắt đầu bằng một số và không được đặt trong dấu ngoặc kép, không có tệp đầu ra nào được tạo.

ví dụ. Invoke-WebRequest -Uri "http://www.google.com/" -outfile "2.pdf"

Điều này không ảnh hưởng đến tên tập tin bắt đầu bằng một chữ cái.


Giải pháp này được đề cập trong các câu trả lời khác ( wgetlà bí danh Invoke-WebRequestvà tương tự như trên)
bertieb

Điểm của câu trả lời là nhấn mạnh vào ghi chú. Không có câu trả lời nào liên quan đến việc không có tệp nào được tạo do lỗi cú pháp.
Zimba

Đó thực sự nên là một nhận xét về câu trả lời khác [s]
bertieb

Câu trả lời này không được cung cấp trong các câu trả lời khác cũng không giống với câu trả lời ở trên.
Zimba

-1

Điều này sẽ làm việc cho bạn để có được xung quanh không có công cụ khởi tạo trình duyệt. Lưu ý thông số "-UseBasicParsing".

Invoke-WebRequest http://localhost -UseBasicParsing

(1) Cái gì là không có trình duyệt khởi tạo thứ gì? (2) Lưu ý rằng câu trả lời được chấp nhận đã đề cập -UseBasicParsing.
Scott
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.