Windowsでwgetする色々な方法

windowsでwgetみたいな事をしたいと思ったときどんな方法があるか調べてみた。
※ https(自己証明書/IPアドレス）でもエラーとならずにダウンロードする方法についても。
（安全とわかっているサイトに対して）

## ツール

### bitsadmin
Windowsに標準で入っているらしい。Windows8で確認

```bat:
bitsadmin.exe /TRANSFER <ジョブ名> <リモートURL> <ダウンロード先>
```
参考URL
http://qiita.com/zembutsu/items/f05d7c5835017fb4c796


### wget for windows
そのまま、wget for windowsというソフトがある。
windows95〜2008まで対応。試していないのでwindows8で使えるかは不明。
インストーラーもあるが、exeとdllを配置するだけでも使える。詳細は参考サイト。

```bat:
wget http://IpAddress/resource -O out.html
```

参考URL
http://www.atmarkit.co.jp/ait/articles/1307/17/news061.html
http://assimane.blog.so-net.ne.jp/2013-01-21

### chocolateyから
[chocolatey](https://chocolatey.org/)にwgetが無いかと探したらあった。
(Linuxでいうyum/apt-getみたいなパッケージ管理ツール）

尚、前述のGNU Wget for windowsと同じものみたいです。
最新版は提供されていないようなので、Wget for windowsを使った方が良いかも。

chocolateyのインストール

```bat:
@powershell -NoProfile -ExecutionPolicy unrestricted -Command "iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))" && SET PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin
```
wgetのインストール

```bat:
choco install Wget
```

実行

```bat:
wget http://IpAddress/resource -O out.html

```

https(自己証明書/IPアドレスでも)の場合は、-no-check-certificateオプションを付ける

```bat:

wget https://IpAddress/resource -O out.html　-no-check
-certificate

```

参考
http://chocolatey.org/packages/Wget
chocolateyの入れ方はこっち
http://millkeyweb.com/win-chocolatey/


### aria2
exe置くだけで使える。分割ダウンロードやBitTorrentと色々な使い方が出来る。

```--check-certificate=false ``` をつけるとSSL証明書の検証は行わない

```bat:
aria2 https://IpAddress/resource/out.html --check-certificate=false
```

参考
http://aria2.sourceforge.net/index-ja.html
http://aria2.sourceforge.net/manual/en/html/aria2c.html




## PowerShell
Windowsに入っていて色々出来ると行ったら、やっぱりPowerShell。.Net Frameworkを呼び出したり、標準でwgetコマンドも用意されている。

### WebClient.Downloadfile
WebClient.DownloadFileメソッド(System.Net)を呼び出す方法
C#/VB.NETで作る場合もこのメソッドを使用する事になるかと。

```ps1:wget.ps1
(new-object System.Net.WebClient).Downloadfile("http://IpAddress/resource", "out.html")
```

### Invoke-WebRequest
PowerShell3.0からInvoke-WebRequestが使える。
エイリアス名がwgetなので、windowsでwgetコマンドは使えると行ってもいい感じ。

```ps1:wget.ps1
Invoke-WebRequest -Uri "http://IpAddress/resource" -OutFile "out.html"

<# Invoke-WebRequestのエイリアスがwgetなのでこれでも可 #>
wget http://IpAddress/resource -OutFile out.html
```
参考URL
http://tech.guitarrapc.com/entry/2013/07/09/220710

httpsページで自己証明書の場合は弾かれてしまうので、下記のようにすると警告が出なくなる。

```ps1:wget_ssl.ps1
add-type @"
    using System.Net;
    using System.Security.Cryptography.X509Certificates;
    public class TrustAllCertsPolicy : ICertificatePolicy {
        public bool CheckValidationResult(
            ServicePoint srvPoint, X509Certificate certificate,
            WebRequest request, int certificateProblem) {
            return true;
        }
    }
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

$result = Invoke-WebRequest -Uri "https://IpAddress/resource" -OutFile "out.html"

```

参考URL
http://suzan2go.hatenablog.com/entry/2014/10/18/192246
http://stackoverflow.com/questions/11696944/powershell-v3-invoke-webrequest-https-error


##Go
 [go](http://golang.jp/)でなんか用意されているんじゃないかと思って調べてみた。goはインストール不要で使えて、exeが作れるので自作の場合はこれが良さげ。


### wget-go
v0.5で完全版じゃないみたい。動くかどうか試してないです。
https://github.com/laher/wget-go

### 書いてみる
参考サイトの記述にコマンドライン引数を指定できるようにした感じ
さらに、https通信はSSL証明書の検証を無視するようにしているので、IPや自己証明書の場合でもOK
詳細は、参考サイトで。

```go:wget.go
package main
import (
  "fmt"
  "io"
  "net/http"
  "crypto/tls"
  "os"
  "flag"
  "path"
)

func main(){

  var filename string
  flag.StringVar(&filename,"o","","output-document")
  flag.Parse()
  url := flag.Args()[0]
  if len(filename) == 0 {
    _ ,filename = path.Split(url)
  }

  transport := &http.Transport{
    TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
  }

  client := &http.Client{
    Transport: transport,
  }

  res, err := client.Get(url)
  if err != nil {
    panic(err)
  }
  defer res.Body.Close()

  file, err := os.Create(filename)
  if err != nil {
    panic(err)
  }
  defer file.Close()
  
  n, err := io.Copy(file, res.Body)
  if err != nil {
    panic(err)
  }
  
  fmt.Println(n, "bytes downloaded.")

}
```

```bash
go run wget.go -o abc.jpg http://example.xx/abc.jpg
go run wget.go http://example.xx/abc.jpg

```

参考
http://kitak.hatenablog.jp/entry/2014/10/19/175133
https://github.com/thbar/golang-playground/blob/master/download-files.go
http://qiita.com/jpshadowapps/items/463b2623209479adcd88
http://tkuchiki.hatenablog.com/entry/2014/07/24/100126


## PHP
PHPもインストール不要でコマンドラインで呼び出せるので、これも良さげ。

### file_get_contentsを使う
https通信の場合は、php.iniの ``` extension=php_openssl.dll ``` が有効になっているか確認。extension_dirも指定されているか確認。``` allow_url_fopen = On ``` とURLをファイルとして開くことが許可されているかも確認。


```php:wget.php

<?php
    $filename=$argv[1];
    $url = $argv[2];
    $data = file_get_contents($url);
    file_put_contents($filename,$data);
?>
```

```bash
php wget.php abc.jpg http://example.xx/abc.jpg
```

###  cURL (Client URL Library) を使う
自己証明書・IPアドレスのhttps通信の場合はcurlを使う。php.iniの ```extension=php_curl.dll ``` を有効になっているか確認。
CURLOPT_SSL_VERIFYPEER、CURLOPT_SSL_VERIFYHOSTをfalseに指定するとサーバ証明書の警告を回避する。

```php:wget.php
<?php
    $filename=$argv[1];
    $url=$argv[2];
    
    //新しい cURL リソースを作成
    $ch = curl_init();
    //ファイルを書き出しのみでオープン
    $fp = fopen($filename, 'w');
    //取得するURLを指定
    curl_setopt($ch, CURLOPT_URL, $url);
    //下記の２つにfalseを設定するとcURLはサーバー証明書の検証行わない
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
　　 //転送内容が書き込まれるファイルポインタを指定
    curl_setopt($ch, CURLOPT_FILE, $fp);
    //指定したcURLセッションを実行
    curl_exec($ch);
    //cURLリソースを閉じ、システムリソースを解放
    curl_close($ch);
 　　//ファイルをクローズ
    fclose($fp);
?>
```

```bash
php wget.php abc.jpg https://example.xx/abc.jpg
```


参考サイト
http://helog.jp/php/xampp/2202/
http://kontany.net/blog/?p=57
http://mio-koduki.blogspot.jp/2012/08/php-curlsslhttpsca.html
http://qiita.com/Hiraku/items/9fb7a0df060e0424921d
http://blog.code4u.org/archives/407
http://php.net/manual/ja/function.curl-setopt.php

## Node.js

httpの場合とhttpsの場合と別れる。

### httpの場合
```js:wget.js
// argv[0]はnode（固定値）、 argv[1]は実行されたjsの絶対パス、2以降はコマンドライン引数の内容
var filename=process.argv[2];
var url=process.argv[3];
//http通信
var http = require('http');
var fs = require('fs');

var file = fs.createWriteStream(filename);
var request = http.get(url, function(response) {
  response.pipe(file);
});

```

```bash
node wge.js abc.jpg http://example.xx/abc.jpg
```

### httpsの場合

process.env.NODE_TLS_REJECT_UNAUTHORIZED =0;
を入れると認証エラーでも通る。

```js:wget_https.js

// argv[0]はnode（固定値）、 argv[1]は実行されたjsの絶対パス、2以降はコマンドライン引数の内容
var filename=process.argv[２];
var url=process.argv[3];

//認証エラーを無視
process.env.NODE_TLS_REJECT_UNAUTHORIZED =0;

//https通信
var https = require('https');
var fs = require('fs');

var file = fs.createWriteStream(filename);
var request = https.get(url, function(response) {
  response.pipe(file);
});

```

```bash
node wget_https.js abc.jpg https://example.xx/abc.jpg
```

参考サイト
http://stackoverflow.com/questions/10888610/ignore-invalid-self-signed-ssl-certificate-in-node-js-with-https-request
http://www.yoheim.net/blog.php?q=20130905



## Python3


### requests

Python3でhttpクライアントは色々あるがrequestsを使用。

```bash:
:: requestsのインストール
pip install requests
```



```py3:wget.py

import sys
import requests
import shutil

param = sys.argv

# verify=Falseで自己証明書でもスキップする
r = requests.get(param[2], stream=True, verify=False)
if r.status_code == 200:
    with open(param[1], 'wb') as f:
        r.raw.decode_content = True
        shutil.copyfileobj(r.raw, f)  
```

```bash
python wget.py abc.jpg https://example.xx/abc.jpg
```

参考サイト
http://momijiame.tumblr.com/post/45560105945/python-http-requests
http://stackoverflow.com/questions/13137817/how-to-download-image-using-requests
http://stackoverflow.com/questions/15445981/how-do-i-disable-the-security-certificate-check-in-python-requests
http://www.python-izm.com/contents/basis/command_line_arguments.shtml
http://d.hatena.ne.jp/s-n-k/20080513/1210692988



## Ruby

[RubyInstaller](http://rubyinstaller.org/) を使ってインストール。

### net/https

```ruby:wget.rb

require "net/https"
require "uri"

uri = URI.parse(ARGV[1])
http = Net::HTTP.new(uri.host,uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE # SSLの検証を無効

request = Net::HTTP::Get.new(uri.request_uri)
response = http.request(request)

# filename = File.basename(uri.request_uri)
filename=ARGV[0]
open(filename, 'wb') do |file|
    file.puts response.body
end
```

```bash
ruby wget.rb abc.jpg https://example.xx/abc.jpg
```

参考URL
http://www.rubyinside.com/nethttp-cheat-sheet-2940.html
http://d.hatena.ne.jp/gan2/20080531/1212227507
http://hideack.hatenablog.com/entry/20111023/1319357035



## Perl

[ActivePerl](http://www.activestate.com/activeperl) を使ってインストール。

下記を予めインストール

```

cpan install LWP::Simple

```


```pl:wget.pl

use LWP::Simple;

$url_save = $ARGV[1];
$file_save = $ARGV[0];
getstore($url_save,$file_save);
```

```bash
Perl wget.pl abc.jpg http://example.xx/abc.jpg
```

https通信する場合は、[openssl](http://www.openssl.org/)（Windowsは、ssleay32.dll と libeay32.dll のファイルだけが必要）が必要。あと　``` Net::SSLaey ``` が必要らしい。詳細は参考URLで。


参考URL
http://memememomo.hatenablog.com/entry/20100826/1282792781
http://www.igreks.jp/dev/2010/02/cryptssleaylwphttps.html
http://blog.livedoor.jp/xaicron/archives/53514791.html
http://www.magicvox.net/archive/2011/11212131/
http://getpopfile.org/docs/jp:howtos:allplatformsrequireperl