bugfix> c# > 投稿

.NET Core 2.0コンソールアプリケーションのドメインに対して、かなり単純なGETリクエストを試みています。

static void Main(string[] args)
{
    MainAsync().Wait();
}
static async Task MainAsync()
{
    var httpClient = new HttpClient();
    var response = await httpClient.GetAsync("https://www.staples.com");
}

これは毎回タイムアウトし、Web例外をスローします。

ウェブサイトにアクセスできますhttps://www.staples.com 私のWebブラウザーで、または問題なくpostmanでGETリクエストを実行し、1秒未満で戻ります。

ドメインで簡単なcurlリクエストを行うこともできますが、それは正常に機能します。

curl https://www.staples.com

私が同じ問題を見つけた別のドメインはhttps://www.safeco.com/

これをChromeブラウザーのリクエストのように見せるためにヘッダーを追加しようとしましたが、違いはありませんでした。

message.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
  "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36");
message.Headers.Add("Accept-Language", "en-US,en;q=0.8");
message.Headers.Add("Cache-Control", "no-cache");
message.Headers.Add("Pragma", "no-cache");
message.Headers.Add("Accept", "text/html,application/xhtml+xml,application/xml;" +
  "q=0.9,image/webp,image/apng,*/*;q=0.8");

これらのドメインで試していない他のURLはすべて正常に動作するようです。これら2つのドメインがHttpClientリクエストでタイムアウトするのはなぜですか?

回答 2 件
  • ほぼ確実に、スクレイピングを防止するための何らかの種類の接続フィルタリングですが、IT部門のみがそれを確認できます。ブラウザーを模倣して正しいヘッダーを送信することで、機能させることができます。このサイトには少なくとも次のものが必要です。

    Connection: keep-alive
    Accept-Encoding: gzip
    Accept-Language: xxx
    
    

    例えば:

    static async Task<string> MainAsync()
    {
        //Added this to decompress the gzip encoded response
        HttpClientHandler handler = new HttpClientHandler();
        handler.AutomaticDecompression = System.Net.DecompressionMethods.GZip;
        var client = new HttpClient(handler);
        var request = new HttpRequestMessage()
        {
            Method = HttpMethod.Get, 
            RequestUri = new Uri("https://www.staples.com"),
            Version = new Version(1, 1)
        };
        request.Headers.Connection.Add("keep-alive");
        request.Headers.AcceptLanguage.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("en-GB"));
        var response = await client.SendAsync(request);
        return await response.Content.ReadAsStringAsync();
    }
    
    

  • 答えではありませんが、コメントにも適切ではありません-これを設定に追加することで、ネットワークトレースから何かを収集できるかもしれません。 initializeData の値を変更するだけ  書き込み可能な場所にリクエストを送信し、出力を確認します。それはきれいではありませんが、手がかりがあるかもしれません。

     <system.diagnostics>
        <sources>
          <source name="System.Net" maxdatasize="102400" tracemode="includehex">
            <listeners>
              <add name="System.Net" />
            </listeners>
          </source>
        </sources>
        <switches>
          <add name="System.Net" value="Verbose" />
        </switches>
        <sharedListeners>
          <add name="System.Net" type="System.Diagnostics.TextWriterTraceListener" initializeData="c:\somewhere...\networkErr.log" />
        </sharedListeners>
      </system.diagnostics>
    
    

あなたの答え