C# HttpWebRequest 絕技 根據URL地址擷取網頁資訊

來源:互聯網
上載者:User

標籤:

如果要使用中間的方法的話,可以訪問我的協助類完全免費開源:C# HttpHelper,協助類,真正的Httprequest請求時無視編碼,無視認證,無視Cookie,網頁抓取1.第一招,根據URL地址擷取網頁資訊   先來看一下代碼get方法複製代碼publicstaticstring GetUrltoHtml(string Url,string type)        {            try            {                System.Net.WebRequest wReq = System.Net.WebRequest.Create(Url);                // Get the response instance.                System.Net.WebResponse wResp = wReq.GetResponse();                System.IO.Stream respStream = wResp.GetResponseStream();                // Dim reader As StreamReader = New StreamReader(respStream)                using (System.IO.StreamReader reader = new System.IO.StreamReader(respStream, Encoding.GetEncoding(type)))                {                    return reader.ReadToEnd();                }            }            catch (System.Exception ex)            {                //errorMsg = ex.Message;            }            return"";        }複製代碼post方法複製代碼  ///<summary>        ///採用https協議訪問網路        ///</summary>        ///<param name="URL">url地址</param>        ///<param name="strPostdata">發送的資料</param>        ///<returns></returns>        publicstring OpenReadWithHttps(string URL,string strPostdata,string strEncoding)        {            Encoding encoding = Encoding.Default;            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);            request.Method ="post";            request.Accept ="text/html, application/xhtml+xml, */*";            request.ContentType ="application/x-www-form-urlencoded";            byte[] buffer= encoding.GetBytes(strPostdata);            request.ContentLength = buffer.Length;            request.GetRequestStream().Write(buffer, 0, buffer.Length);            HttpWebResponse response = (HttpWebResponse)request.GetResponse();            using( StreamReader reader =new StreamReader(response.GetResponseStream(), System.Text.Encoding.GetEncoding(strEncoding)))              {                   return reader.ReadToEnd();              }        }複製代碼這招是入門第一式, 特點:   1.最簡單最直觀的一種,入門課程。   2.適應於明文,無需登入,無需任何驗證就可以進入的頁面。   3.擷取的資料類型為HTML文檔。   4.要求方法為Get/Post2.第二招,根據URL地址擷取需要驗證認證才能訪問的網頁資訊   先來看一下代碼get方法複製代碼  //回調驗證認證問題        publicbool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)        {   // 總是接受               returntrue;        }        /// <summary>        /// 傳入URL返回網頁的html代碼        /// </summary>        /// <param name="Url">URL</param>        /// <returns></returns>        publicstring GetUrltoHtml(string Url)        {            StringBuilder content =new StringBuilder();            try            {                //這一句一定要寫在建立串連的前面。使用回調的方法進行認證驗證。                ServicePointManager.ServerCertificateValidationCallback=new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);                // 與指定URL建立HTTP請求                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);                //建立認證檔案                X509Certificate objx509 = new X509Certificate(Application.StartupPath+"\\123.cer");                //添加到請求裡                request.ClientCertificates.Add(objx509);                // 擷取對應HTTP請求的響應                HttpWebResponse response = (HttpWebResponse)request.GetResponse();                // 擷取響應流                Stream responseStream = response.GetResponseStream();                // 對接響應流(以"GBK"字元集)                StreamReader sReader =new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));                // 開始讀取資料                Char[] sReaderBuffer =new Char[256];                int count= sReader.Read(sReaderBuffer,0,256);                while (count>0)                {                    String tempStr =new String(sReaderBuffer,0, count);                    content.Append(tempStr);                    count = sReader.Read(sReaderBuffer,0,256);                }                // 讀取結束                sReader.Close();            }            catch (Exception)            {                content =new StringBuilder("Runtime Error");            }            return content.ToString();        }複製代碼post方法複製代碼   //回調驗證認證問題        publicbool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)        {            // 總是接受               returntrue;        }        ///<summary>        ///採用https協議訪問網路        ///</summary>        ///<param name="URL">url地址</param>        ///<param name="strPostdata">發送的資料</param>        ///<returns></returns>        publicstring OpenReadWithHttps(string URL,string strPostdata,string strEncoding)        {            // 這一句一定要寫在建立串連的前面。使用回調的方法進行認證驗證。            ServicePointManager.ServerCertificateValidationCallback=new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);            Encoding encoding = Encoding.Default;            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);            //建立認證檔案            X509Certificate objx509 =new X509Certificate(Application.StartupPath+"\\123.cer");            //載入Cookie            request.CookieContainer =new CookieContainer();            //添加到請求裡            request.ClientCertificates.Add(objx509);            request.Method ="post";            request.Accept ="text/html, application/xhtml+xml, */*";            request.ContentType ="application/x-www-form-urlencoded";            byte[] buffer= encoding.GetBytes(strPostdata);            request.ContentLength = buffer.Length;            request.GetRequestStream().Write(buffer, 0, buffer.Length);            HttpWebResponse response = (HttpWebResponse)request.GetResponse();            using (StreamReader reader =new StreamReader(response.GetResponseStream(), System.Text.Encoding.GetEncoding(strEncoding)))               {                   return reader.ReadToEnd();               }        }複製代碼這招是學會算是進了大門了,凡是需要驗證認證才能進入的頁面都可以使用這個方法進入,我使用的是認證回調驗證的方式,認證驗證是否通過在用戶端驗證,這樣的話我們就可以使用自己定義一個方法來驗證了,有的人會說那也不清楚是怎麼樣驗證的啊,其它很簡單,代碼是自己寫的為什麼要那麼難為自己呢,直接返回一個True不就完了,永遠都是驗證通過,這樣就可以無視認證的存在了, 特點:   1.入門前的小難題,初級課程。   2.適應於無需登入,明文但需要驗證認證才能訪問的頁面。   3.擷取的資料類型為HTML文檔。   4.要求方法為Get/Post3.第三招,根據URL地址擷取需要登入才能訪問的網頁資訊        我們先來分析一下這種類型的網頁,需要登入才能訪問的網頁,其它呢也是一種驗證,驗證什麼呢,驗證用戶端是否登入,是否具用相應的憑證,需要登入的都要驗證SessionID這是每一個需要登入的頁面都需要驗證的,那我們怎麼做的,我們第一步就是要得存在Cookie裡面的資料包括SessionID,那怎麼得到呢,這個方法很多,使用ID9或者是Firefox瀏覽器很容易就能得到,可以參考我的文章提供一個網頁抓取hao123手機號碼歸屬地的例子   這裡面針對ID9有詳細的說明。如果我們得到了登入的Cookie資訊之後那個再去訪問相應的頁面就會非常的簡單了,其它說白了就是把本地的Cookie資訊在請求的時候捎帶過去就行了。   看代碼get方法View Code///<summary>        /// 傳入URL返回網頁的html代碼帶有認證的方法        /// </summary>        /// <param name="Url">URL</param>        /// <returns></returns>        publicstring GetUrltoHtml(string Url)        {            StringBuilder content =new StringBuilder();            try            {                // 與指定URL建立HTTP請求                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);                request.UserAgent ="Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; BOIE9;ZHCN)";                request.Method ="GET";                request.Accept ="*/*";                //如果方法驗證網頁來源就加上這一句如果不驗證那就可以不寫了                request.Referer ="http://sufei.cnblogs.com";                CookieContainer objcok =new CookieContainer();                objcok.Add(new Uri("http://sufei.cnblogs.com"),new Cookie("鍵","值"));                objcok.Add(new Uri("http://sufei.cnblogs.com"),new Cookie("鍵","值"));                objcok.Add(new Uri("http://sufei.cnblogs.com"),new Cookie("sidi_sessionid","360A748941D055BEE8C960168C3D4233"));                request.CookieContainer = objcok;                //不保持串連                request.KeepAlive =true;                // 擷取對應HTTP請求的響應                HttpWebResponse response = (HttpWebResponse)request.GetResponse();                // 擷取響應流                Stream responseStream = response.GetResponseStream();                // 對接響應流(以"GBK"字元集)                StreamReader sReader =new StreamReader(responseStream, Encoding.GetEncoding("gb2312"));                // 開始讀取資料                Char[] sReaderBuffer =new Char[256];                int count= sReader.Read(sReaderBuffer,0,256);                while (count>0)                {                    String tempStr =new String(sReaderBuffer,0, count);                    content.Append(tempStr);                    count = sReader.Read(sReaderBuffer,0,256);                }                // 讀取結束                sReader.Close();            }            catch (Exception)            {                content =new StringBuilder("Runtime Error");            }            return content.ToString();        }post方法。View Code///<summary>        ///採用https協議訪問網路        ///</summary>        ///<param name="URL">url地址</param>        ///<param name="strPostdata">發送的資料</param>        ///<returns></returns>        publicstring OpenReadWithHttps(string URL,string strPostdata)        {            Encoding encoding = Encoding.Default;            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);            request.Method ="post";            request.Accept ="text/html, application/xhtml+xml, */*";            request.ContentType ="application/x-www-form-urlencoded";            CookieContainer objcok =new CookieContainer();            objcok.Add(new Uri("http://sufei.cnblogs.com"),new Cookie("鍵","值"));            objcok.Add(new Uri("http://sufei.cnblogs.com"),new Cookie("鍵","值"));            objcok.Add(new Uri("http://sufei.cnblogs.com"),new Cookie("sidi_sessionid","360A748941D055BEE8C960168C3D4233"));            request.CookieContainer = objcok;            byte[] buffer= encoding.GetBytes(strPostdata);            request.ContentLength = buffer.Length;            request.GetRequestStream().Write(buffer, 0, buffer.Length);            HttpWebResponse response = (HttpWebResponse)request.GetResponse();            StreamReader reader =new StreamReader(response.GetResponseStream(), System.Text.Encoding.GetEncoding("utf-8"));            return reader.ReadToEnd();        }特點:   1.還算有點水類型的,練習成功後可以小牛一把。   2.適應於需要登入才能訪問的頁面。   3.擷取的資料類型為HTML文檔。   4.要求方法為Get/Post總結一下,其它基本的技能就這幾個部分,如果再深入的話那就是基本技能的組合了比如,1. 先用Get或者Post方法登入然後取得Cookie再去訪問頁面得到資訊,這種其它也是上面技能的組合,這裡需要以請求後做這樣一步response.Cookies這就是在你請求後可以得到當次Cookie的方法,直接取得返回給上一個方法使用就行了,上面我們都是自己構造的,在這裡直接使用這個Cookie就可以了。2.如果我們碰到需要登入而且還要驗證認證的網頁怎麼辦,其它這個也很簡單把我們上面的方法綜合 一下就行了如下代碼這裡我以Get為例子Post例子也是同樣的方法View Code  ///<summary>        /// 傳入URL返回網頁的html代碼        /// </summary>        /// <param name="Url">URL</param>        /// <returns></returns>        publicstring GetUrltoHtml(string Url)        {            StringBuilder content =new StringBuilder();            try            {                //這一句一定要寫在建立串連的前面。使用回調的方法進行認證驗證。                ServicePointManager.ServerCertificateValidationCallback=new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);                // 與指定URL建立HTTP請求                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);                //建立認證檔案                X509Certificate objx509 = new X509Certificate(Application.StartupPath+"\\123.cer");                //添加到請求裡                request.ClientCertificates.Add(objx509);                CookieContainer objcok =new CookieContainer();                objcok.Add(new Uri("http://www.cnblogs.com"),new Cookie("鍵","值"));                objcok.Add(new Uri("http://www.cnblogs.com"),new Cookie("鍵","值"));                objcok.Add(new Uri("http://www.cnblogs.com"),new Cookie("sidi_sessionid","360A748941D055BEE8C960168C3D4233"));                request.CookieContainer = objcok;                // 擷取對應HTTP請求的響應                HttpWebResponse response = (HttpWebResponse)request.GetResponse();                // 擷取響應流                Stream responseStream = response.GetResponseStream();                // 對接響應流(以"GBK"字元集)                StreamReader sReader =new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));                // 開始讀取資料                Char[] sReaderBuffer =new Char[256];                int count= sReader.Read(sReaderBuffer,0,256);                while (count>0)                {                    String tempStr =new String(sReaderBuffer,0, count);                    content.Append(tempStr);                    count = sReader.Read(sReaderBuffer,0,256);                }                // 讀取結束                sReader.Close();            }            catch (Exception)            {                content =new StringBuilder("Runtime Error");            }            return content.ToString();        }3.如果我們碰到那種需要驗證網頁來源的方法應該怎麼辦呢,這種情況其它是有些程式員會想到你可能會使用程式,自動來擷取網頁資訊,為了防止就使用頁面來源來驗證,就是說只要不是從他們所在頁面或是網域名稱過來的請求就不接受,有的是直接驗證來源的IP,這些都可以使用下面一句來進入,這主要是這個地址是可以直接偽造的          request.Referer ="http://sufei.cnblogs.com";呵呵其它很簡單因為這個地址可以直接修改。但是如果伺服器上驗證的是來源的URL那就完了,我們就得去修改資料包了,這個有點難度暫時不討論。4.提供一些與這個例子相配置的方法    過濾HTML標籤的方法View Code  ///<summary>        /// 過濾html標籤        /// </summary>        /// <param name="strHtml">html的內容</param>        /// <returns></returns>        publicstaticstring StripHTML(string stringToStrip)        {            // paring using RegEx          //            stringToStrip = Regex.Replace(stringToStrip,"</p(?:\\s*)>(?:\\s*)<p(?:\\s*)>","\n\n", RegexOptions.IgnoreCase| RegexOptions.Compiled);            stringToStrip = Regex.Replace(stringToStrip,"<br(?:\\s*)/>","\n", RegexOptions.IgnoreCase| RegexOptions.Compiled);            stringToStrip = Regex.Replace(stringToStrip,"\"","‘‘", RegexOptions.IgnoreCase| RegexOptions.Compiled);            stringToStrip = StripHtmlXmlTags(stringToStrip);            return stringToStrip;        }        privatestaticstring StripHtmlXmlTags(string content)        {            return Regex.Replace(content,"<[^>]+>","", RegexOptions.IgnoreCase| RegexOptions.Compiled);        }     URL轉化的方法複製代碼  #region 轉化 URL        publicstaticstring URLDecode(string text)        {            return HttpUtility.UrlDecode(text, Encoding.Default);        }        publicstaticstring URLEncode(string text)        {            return HttpUtility.UrlEncode(text, Encoding.Default);        }        #endregion複製代碼提供一個實際例子,這個是使用IP138來查詢手機號碼歸屬地的方法,其它在我的上一次文章裡都有,在這裡我再放上來是方便大家閱讀,這方面的技術其它研究起來很有意思,希望大家多提建議,我相信應該還有更多更好,更完善的方法,在這裡給大家提供一個參考吧。感謝支援上例子複製代碼        ///<summary>        /// 輸入手機號碼得到歸屬地資訊        /// </summary>        /// <param name="number">手機號碼</param>        /// <returns>數群組類型0為歸屬地,1卡類型,2區 號,3郵 編</returns>        publicstaticstring[] getTelldate(string number)        {            try            {                string strSource= GetUrltoHtml("http://www.ip138.com:8080/search.asp?action=mobile&mobile="+ number.Trim());                //歸屬地                strSource = strSource.Substring(strSource.IndexOf(number));                strSource = StripHTML(strSource);                strSource = strSource.Replace("\r","");                strSource = strSource.Replace("\n","");                strSource = strSource.Replace("\t","");                strSource = strSource.Replace(" ","");                strSource = strSource.Replace("-->","");                string[] strnumber= strSource.Split(newstring[] { "歸屬地","卡類型","郵 編","區 號","更詳細","卡號" }, StringSplitOptions.RemoveEmptyEntries);                string[] strnumber1=null;                if (strnumber.Length>4)                {                    strnumber1 =newstring[] { strnumber[1].Trim(), strnumber[2].Trim(), strnumber[3].Trim(), strnumber[4].Trim() };                }                return strnumber1;            }            catch (Exception)            {                returnnull;            }        }複製代碼這個例子寫是不怎麼樣,些地方是可以簡化的,這個介面而且可以直接使用Xml得到,但我在這裡的重點是讓一些新手看看方法和思路風涼啊,呵呵第四招,通過Socket訪問------------------------------------------------------------------------------------------------------------複製代碼 ///<summary>        /// 請求的公用類用來向伺服器發送請求        ///</summary>        ///<param name="strSMSRequest">發送請求的字串</param>        ///<returns>返回的是請求的資訊</returns>        private static string SMSrequest(string strSMSRequest)        {            byte[] data = new byte[1024];            string stringData = null;            IPHostEntry gist = Dns.GetHostByName("www.110.cn");            IPAddress ip = gist.AddressList[0];            //得到IP             IPEndPoint ipEnd = new IPEndPoint(ip, 3121);            //預設80連接埠號碼             Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);            //使用tcp協議 stream類型             try            {                socket.Connect(ipEnd);            }            catch (SocketException ex)            {                return "Fail to connect server\r\n" + ex.ToString();            }            string path = strSMSRequest.ToString().Trim();            StringBuilder buf = new StringBuilder();            //buf.Append("GET ").Append(path).Append(" HTTP/1.0\r\n");            //buf.Append("Content-Type: application/x-www-form-urlencoded\r\n");            //buf.Append("\r\n");            byte[] ms = System.Text.UTF8Encoding.UTF8.GetBytes(buf.ToString());            //提交請求的資訊            socket.Send(ms);            //接收返回             string strSms = "";            int recv = 0;            do            {                recv = socket.Receive(data);                stringData = Encoding.ASCII.GetString(data, 0, recv);                //如果請求的頁面meta中指定了頁面的encoding為gb2312則需要使用對應的Encoding來對位元組進行轉換()                 strSms = strSms + stringData;                //strSms += recv.ToString();            }            while (recv != 0);            socket.Shutdown(SocketShutdown.Both);            socket.Close();            return strSms;        }

 

C# HttpWebRequest 絕技 根據URL地址擷取網頁資訊

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.