2016-06-22 4 views
2

私は、robots.txtファイルをnike.comから入手するという単純な要求があります。 Goの通常のGET要求は、ファイルを期待通りに返します。現在のブラウザ(Chrome)ではファイルにアクセスできます。しかし、GoのUAをブラウザのブラウザと同じに変更しようとすると、403エラーが発生します。ユーザエージェントを変更すると、なぜ私は拒否されますか?

つまり、Goのデフォルト設定を使用してページにアクセスしてコードが正しいことを証明できますが、UAを変更すると403が表示されます(ブラウザで同じUAが機能しています)。

UAを何かランダムに変更した場合(例:「Not me」)、200となります。なぜブラウザのUAを使用できないのですか?

package main 

import (
    "log" 
    "net/http" 

    "github.com/davecgh/go-spew/spew" 
) 

func main() { 
    var resp *http.Response 
    var err error 
    u := "http://www.nike.com/robots.txt" 

    for _, ua := range []bool{false, true} { 
     client := &http.Client{} 
     req, _ := http.NewRequest("GET", u, nil) 
     if ua == true { 
      req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36") 
     } 
     resp, err = client.Do(req) 
     if err != nil { 
      log.Fatalln(err) 
     } 
     log.Println("StatusCode", resp.StatusCode) 
     spew.Dump(resp.Request) 
     log.Println("----------------------------") 
    } 

} 

応答:

2016/06/22 16:56:57 StatusCode 200 
(*http.Request)(0xc8200d02a0)({ 
Method: (string) (len=3) "GET", 
URL: (*url.URL)(0xc820076280)(http://www.nike.com/robots.txt), 
Proto: (string) (len=8) "HTTP/1.1", 
ProtoMajor: (int) 1, 
ProtoMinor: (int) 1, 
Header: (http.Header) { 
}, 
Body: (io.ReadCloser) <nil>, 
ContentLength: (int64) 0, 
TransferEncoding: ([]string) <nil>, 
Close: (bool) false, 
Host: (string) (len=12) "www.nike.com", 
Form: (url.Values) <nil>, 
PostForm: (url.Values) <nil>, 
MultipartForm: (*multipart.Form)(<nil>), 
Trailer: (http.Header) <nil>, 
RemoteAddr: (string) "", 
RequestURI: (string) "", 
TLS: (*tls.ConnectionState)(<nil>), 
Cancel: (<-chan struct {}) <nil> 
}) 
2016/06/22 16:56:57 ---------------------------- 
2016/06/22 16:56:57 StatusCode 403 
(*http.Request)(0xc820110000)({ 
Method: (string) (len=3) "GET", 
URL: (*url.URL)(0xc8200ea180)(http://www.nike.com/robots.txt), 
Proto: (string) (len=8) "HTTP/1.1", 
ProtoMajor: (int) 1, 
ProtoMinor: (int) 1, 
Header: (http.Header) (len=1) { 
    (string) (len=10) "User-Agent": ([]string) (len=1 cap=1) { 
    (string) (len=104) "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36" 
    } 
}, 
Body: (io.ReadCloser) <nil>, 
ContentLength: (int64) 0, 
TransferEncoding: ([]string) <nil>, 
Close: (bool) false, 
Host: (string) (len=12) "www.nike.com", 
Form: (url.Values) <nil>, 
PostForm: (url.Values) <nil>, 
MultipartForm: (*multipart.Form)(<nil>), 
Trailer: (http.Header) <nil>, 
RemoteAddr: (string) "", 
RequestURI: (string) "", 
TLS: (*tls.ConnectionState)(<nil>), 
Cancel: (<-chan struct {}) <nil> 
}) 
2016/06/22 16:56:57 ---------------------------- 

EDIT: 私は少し周りプレーしてきたと私はクロームが送信するすべての他のヘッダを設定した場合、それは動作します。

+1

興味深い! "クロム"のユーザーエージェントは403を返します。 "クロム"のユーザーエージェントは200を返します。おそらくナイキはあなたがブラウザを偽装しようとしていると考えますか? – Mark

答えて

-1

あなたのテストコードは、同じHTTPクライアントオブジェクトを使用して両方のリクエストを送信します。おそらく両方が同じ接続を経由します。

異なる接続でリクエストを送信しようとしましたか?あなたのフラグをtrueとfalseに設定してみて、それが常に失敗したかどうかを確認してください。

+0

w/no幸運を注文してみました。私はちょっと遊んでいました。もし私がクロムが送る他のすべてのヘッダーを設定すると、それは動作します。なぜナイキがそうしているのだろう... –

+2

@kristen:このサイトは悪質な活動を防止しようとしています。あなたがクロームブラウザではなく、クロムユーザーエージェントを取得していることがわかっている場合、リクエストを拒否します。 – JimB

+1

私の次の提案 - 他のすべてのヘッダを見直すことでした。何らかの種類の指紋があるはずです。 UA文字列は、さまざまなクライアント間で非常によく似ています。 – Adrien

関連する問題