1 webrequest 是什么:編程方式模擬web請求,利用webrequest可以實現 相當於一個瀏覽器請求一個網頁的效果,但是它始終是模擬請求,
與瀏覽器輸入框輸入網址請求不一樣。
2 程序設計中有時有這樣的case,需要請求一個url,獲得特定網頁的部分html代碼,比如特定的table,div片段。
這個時候可以用代碼實現一個httpwebrequest請求,以get的方式請求遠程站點的一個url,返回結果是網頁的整個html,之后再在結果中提取我們需要的數據。
代碼如下
#region WebRequest請求url /// <summary> /// WebRequest請求url /// </summary> /// <param name="reqUrl">服務端URl</param> /// <param name="method">方法大寫(POST)</param> /// <returns>返回Xml格式字符串</returns> public string CreateRequest(string reqUrl, string method, string param) { string error = string.Empty; string resultStr = string.Empty; HttpWebRequest webReq = (HttpWebRequest)HttpWebRequest.Create(reqUrl); webReq.Method = method; webReq.KeepAlive = true; webReq.Timeout = 20000; webReq.ContentType = "text/html";//application/x-www-form-urlencoded webReq.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)"; if (method == "POST") { byte[] bs = Encoding.ASCII.GetBytes(param); webReq.ContentLength = bs.Length; using (Stream reqStream = webReq.GetRequestStream()) { reqStream.Write(bs, 0, bs.Length); } } using (HttpWebResponse response = (HttpWebResponse)webReq.GetResponse()) { using (StreamReader reader = new StreamReader(response.GetResponseStream())) { resultStr = reader.ReadToEnd(); } if (response != null) response.Close(); } return GetChartSize(resultStr); } #endregion
在遠程站點服務器不做任何限制的情況下,這樣的單個請求一般都會成功。
有幾種情況需要注意。
1 整個過程是一個客戶端服務端的完整請求,請求結束后要記得關閉連接,使用using是一個好的習慣。否則后果很嚴重
2 我做過的關於webrequest的幾個項目都涉及到循環請求web服務器,比如我是先得到一個產品信息列表,假設有一次200條,其中一條商品信息有一個url值,
必須webrequest去請求網頁獲得一段html,之后我分析完這段html后再去請求,這樣循環發送,相當於攻擊了。一定數量的產品信息列表就可以循環發起請求了。一段時間后不穩定情況就出現了。
明明存在的url,在請求的時候就報url不存在了。
原因:但某一個請求一段時間后得不到回應,請求會中斷,之后的請求也就失敗了:
The remote server returned an error: (404) Not Found.
at System.Net.HttpWebRequest.GetResponse()
實際上根本是存在的url
3 .NET對連接有數最的限制,可以設置ServicePointManager.DefaultConnectionLimit修改限制數量。
頻繁的請求可能跟連接限制有關系,我對.NET連接限制的原理不是很清楚,在我的代碼和webconfig分別把這個連接數設置為
512,結果沒有起任何作用。
我自己測試ServicePointManager.DefaultConnectionLimit的默認值是21
4 關於這個問題的一些參考資料
》http://www.cnblogs.com/Thriving-Country/archive/2009/12/18/1627008.html
這里詳細的解釋了並發連接,
http://q.cnblogs.com/q/34850/
http://topic.csdn.net/u/20070403/15/e2fc87fb-4795-4c50-9c21-934a46079e62.html
我的建議:
根據我自己的經驗,循環使用webrequest請求遠程網頁的做法不是一個科學可靠的設計方案,
這樣做不穩定而且風險巨大,一定數量級的頻繁請求肯定會出問題。程序需要的數據最好還是預先放在數據庫中做持久化處理。
像我描述的這種case還有一種解決方法是:直接讀取服務器上的html文件,根據業務關系獲取相應的信息,將需要的數據存放到數據庫中