簡體   English   中英

WebClient掛起直到超時

[英]WebClient hangs until timeout

我嘗試使用WebClient下載網頁,但該網頁一直掛起,直到達到WebClient的超時,然后失敗並顯示Exception。

以下代碼不起作用

WebClient client = new WebClient();
string url = "https://www.nasdaq.com/de/symbol/aapl/dividend-history";
string page = client.DownloadString(url);

使用其他URL,傳輸可以正常進行。 例如

WebClient client = new WebClient();
string url = "https://www.ariva.de/apple-aktie";
string page = client.DownloadString(url);

完成非常快,並且頁面變量中包含整個html。

使用HttpClient或WebRequest / WebResponse在第一個URL:塊上給出相同的結果:直到超時異常。

這兩個URL都可以在瀏覽器中正常加載,大約需要2-5秒鍾。 任何想法是什么問題,有什么解決方案可用?

我注意到,在Windows窗體對話框上使用WebBrowser控件時,第一個URL加載了20多個javascript錯誤,需要確認單擊。 當訪問第一個URL時,在瀏覽器中打開開發人員工具時,也會看到相同的結果。

但是,WebClient不會對其獲得的回報采取行動。 它不會運行javascript,也不會加載引用的圖片,css或其他腳本,因此這應該不是問題。

謝謝!

拉爾夫

第一個網站"https://www.nasdaq.com/de/symbol/aapl/dividend-history"; ,要求:

這里的User-agent很重要。 如果在WebRequest.UserAgent中指定了最新的User-agent ,則WebSite將激活僅由最近的瀏覽器(作為參考,FireFox 56或更高版本)支持/理解的Http 2.0協議和HSTSHTTP Strict Transport Security )。 。

必須使用較新的瀏覽器作為User-agent ,否則WebSite將期待(並等待) 動態響應。 使用較舊的 User-agent ,WebSite將激活Http 1.1協議。

第二個站點"https://www.ariva.de/apple-aktie"; ,要求:

  • ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
  • 無需服務器證書驗證
  • 不需要特定的用戶代理

我建議以這種方式設置WebRequest(或相應的HttpClient設置):
(WebClient 可以工作,但是可能需要派生的自定義控件)

private async void button1_Click(object sender, EventArgs e)
{
    button1.Enabled = false;
    Uri uri = new Uri("https://www.nasdaq.com/de/symbol/aapl/dividend-history");
    string destinationFile = "[Some Local File]";
    await HTTPDownload(uri, destinationFile);
    button1.Enabled = true;
}


CookieContainer httpCookieJar = new CookieContainer();

//The 32bit IE11 header is the User-agent used here
public async Task HTTPDownload(Uri resourceURI, string filePath)
{
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
    ServicePointManager.ServerCertificateValidationCallback += (s, cert, ch, sec) => { return true; };
    ServicePointManager.DefaultConnectionLimit = 50;

    HttpWebRequest httpRequest = WebRequest.CreateHttp(resourceURI);

    try
    {
        httpRequest.CookieContainer = httpCookieJar;
        httpRequest.Timeout = (int)TimeSpan.FromSeconds(15).TotalMilliseconds;
        httpRequest.AllowAutoRedirect = true;
        httpRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
        httpRequest.ServicePoint.Expect100Continue = false;
        httpRequest.UserAgent = "Mozilla / 5.0(Windows NT 6.1; WOW32; Trident / 7.0; rv: 11.0) like Gecko";
        httpRequest.Accept = "ext/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
        httpRequest.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate;q=0.8");
        httpRequest.Headers.Add(HttpRequestHeader.CacheControl, "no-cache");

        using (HttpWebResponse httpResponse = (HttpWebResponse)await httpRequest.GetResponseAsync())
        using (Stream responseStream = httpResponse.GetResponseStream())
        {
            if (httpResponse.StatusCode == HttpStatusCode.OK)
            {
                try
                {
                    int buffersize = 132072;
                    using (FileStream fileStream = File.Create(filePath, buffersize, FileOptions.Asynchronous))
                    {
                        int read;
                        byte[] buffer = new byte[buffersize];
                        while ((read = await responseStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
                        {
                            await fileStream.WriteAsync(buffer, 0, read);
                        }
                    };
                }
                catch (DirectoryNotFoundException) { /* Log or throw */}
                catch (PathTooLongException) { /* Log or throw */}
                catch (IOException) { /* Log or throw */}
            }
        };
    }
    catch (WebException) { /* Log and message */} 
    catch (Exception) { /* Log and message */}
}

返回的第一個WebSite( nasdaq.com )有效負載長度為101.562字節
返回的第二個網站( www.ariva.de )的有效載荷長度為56.919字節

顯然,下載該鏈接存在問題(錯誤的url,未經授權的訪問等),但是您可以使用異步方法來解決存儲部分:

  WebClient client = new WebClient();
  client.DownloadStringCompleted += (s, e) =>
  {
       //here deal with downloaded file
  };
  client.DownloadStringAsync(url);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM