Dot-Net

十個連續請求後的 HttpWebRequest 超時

  • September 30, 2014

我正在為特定站點編寫網路爬蟲。該應用程序是一個使用多個執行緒的 VB.Net Windows 窗體應用程序 - 每個 Web 請求都是連續的。但是,在十次成功的頁面檢索之後,每個連續的請求都會超時。

我已經查看了已經在 SO 上發布的類似問題,並將推薦的技術實施到我的 GetPage 常式中,如下所示:

Public Function GetPage(ByVal url As String) As String
   Dim result As String = String.Empty

   Dim uri As New Uri(url)
   Dim sp As ServicePoint = ServicePointManager.FindServicePoint(uri)
   sp.ConnectionLimit = 100

   Dim request As HttpWebRequest = WebRequest.Create(uri)
   request.KeepAlive = False
   request.Timeout = 15000

   Try
       Using response As HttpWebResponse = DirectCast(request.GetResponse, HttpWebResponse)
           Using dataStream As Stream = response.GetResponseStream()
               Using reader As New StreamReader(dataStream)
                   If response.StatusCode <> HttpStatusCode.OK Then
                       Throw New Exception("Got response status code: " + response.StatusCode)
                   End If
                   result = reader.ReadToEnd()
               End Using
           End Using
           response.Close()
       End Using

   Catch ex As Exception
       Dim msg As String = "Error reading page """ & url & """. " & ex.Message
       Logger.LogMessage(msg, LogOutputLevel.Diagnostics)
   End Try

   Return result

End Function

我錯過了什麼嗎?我是否沒有關閉或處置應該是的對象?它總是在連續十個請求之後發生,這似乎很奇怪。

筆記:

  1. 在此方法所在的類的建構子中,我有以下內容:

ServicePointManager.DefaultConnectionLimit = 100 2. 如果我將 KeepAlive 設置為 true,則超時在五個請求後開始。 3. 所有請求都針對同一域中的頁面。

編輯

我在每個 Web 請求之間添加了 2 到 7 秒的延遲,這樣我就不會“敲擊”該站點或嘗試進行 DOS 攻擊。但是,問題仍然存在。

我認為該站點具有某種 DOS 保護,當它受到許多 rapis 請求的打擊時就會啟動。您可能想嘗試在 webrequest 上設置 UserAgent。

我今天遇到了這個問題,我的決定是確保始終關閉響應。

我認為您需要在使用中拋出異常之前放入 response.Close()。

Using response As HttpWebResponse = DirectCast(request.GetResponse, HttpWebResponse) 
       Using dataStream As Stream = response.GetResponseStream() 
           Using reader As New StreamReader(dataStream) 
               If response.StatusCode <> HttpStatusCode.OK Then 
                   response.Close()  
                   Throw New Exception("Got response status code: " + response.StatusCode) 
               End If 
               result = reader.ReadToEnd() 
           End Using 
       End Using 
       response.Close() 
   End Using

引用自:https://stackoverflow.com/questions/1191926