採集需要登入後的網頁(重新導向後cookie丟失問題)

來源:互聯網
上載者:User

 

   在採集需要登陸後訪問的頁面中,採集程式需要儲存登入後擷取的cookie,由於有些網站登入驗證成功後就將使用者直接重新導向到目標頁,
如: Response.Redirect("/user/index.asp") 
回應標頭部含如下參數
Location: /user/index.aspx
Set-Cookie: .ASPXAUTH=3DABFC1691FD31F16EFF68D55202130196135D8B3F0A8B630C956242FBBA802EDB912E0B84D6601A6F425824DA1C28AFBDF04E6B4D0CA6E7D7EBB7DD2A212F5FFFF2921DF35CE098F603CE31E56D71AD68CC23117123E11AB8323AD86B648665; expires=Thu, 04-Dec-2008 02:59:15 GMT; path=/; HttpOnly
這樣在使用WebClient時,不能捕捉到需要的cookie,這個時候就需要使用HttpWebRequest(WebRequest針對http協議的實現)

擷取cookieContainer

---------------------------------------
        private System.Net.CookieContainer GetCookieContainer(string logUrl,byte[] data)
        {
            HttpWebRequest request = HttpWebRequest.Create(logUrl) as HttpWebRequest;
            request.AllowAutoRedirect = false;//禁止自動重新導向
            request.Method = "Post"; //使用post方法
            request.ContentType = "application/x-www-form-urlencoded";//form提交時使用urlencode
            request.ContentLength = data.Length;
            request.CookieContainer = new CookieContainer();
            Stream uploadStream=request.GetRequestStream();
            uploadStream.Write(data, 0, data.Length);
            uploadStream.Close();
            HttpWebResponse resposne = request.GetResponse() as HttpWebResponse;
            resposne.Close();
            return request.CookieContainer;//反會擷取的cookieContainer
        }

 //登入後擷取cookie再進行資料擷取,需要導如System.IO,System.Net,System.Web等命名空間

 

 -------------------------------------------------

            string formData=@"Username=xxxx&Password=dafa34@234";//登入頁面表單欄位
            //使用gb2312進行Url編碼
            formData= HttpUtility.UrlEncode(formData,Encoding.GetEncoding("gb2312"));
            //編碼為位元組資料
            byte[] data = Encoding.GetEncoding("gb2312").GetBytes(formData);

            //是需要登陸後擷取的頁面(資料擷取頁)
            Uri dataUri = new Uri("http://wow52.cn/admin/article.aspx");
            HttpWebRequest request = WebRequest.Create(dataUri) as HttpWebRequest;
            
           //設定來路,有些網站會檢測訪問來路來判斷是否為盜鏈等.
           //使用WebRequest時你無法直接使用 request.Hands.Add("Referer","http://www.wow52.cn/log.aspx")
           //來添加標題
            request.Referer="http://www.wow52.cn/log.aspx";
            //一些其他設定
            //request.Accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-silverlight, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */*";
            //request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)";
            request.Method = "GET";
            //登入頁地址,需要特別注意的是這個uri的網域名稱必須要與上面一致
            //使用www.wow52.cn擷取的cookieContainer只有在網域名稱為www.wow52.cn時才會被附加上
            //對一些使用了次層網域的網站,各資料頁次層網域各不相同的,可以將Cookie逐個取出
            //再拼接起來,如: cookieName1=cookieValue1;cookieName2=cookieValue2;...
            //將拼字後的字串添加到Request.Headers中如:request.Headers.Add("Cookie", "拼接串");
            Uri logUri = new Uri("http://www.wow52.cn/log.aspx"); //這裡設定為http://www.wow52.cn/區別上面dataUri的wow52.cn

            //調用上文的GetCookieContainer函數
            CookieContainer container = GetCookieContainer(logUri.ToString(), data);
          

//判斷是否是同個網域名稱(主機名稱)
 if (Uri.Compare(dataUri, logUri, UriComponents.Host, UriFormat.SafeUnescaped, StringComparison.OrdinalIgnoreCase) != 0)
            {
                //逐個取出cookie並更改domain後,添加到request.CookieContainer中

                CookieCollection cookies = container.GetCookies(logUri);
                request.CookieContainer = new CookieContainer();
                foreach (Cookie cookie in cookies)
                {
                    cookie.Domain = dataUri.Host; //使用目標資料頁的主機部分
                    request.CookieContainer.Add(cookie);
                }
         
            }
            else //domain相同
            {
                request.CookieContainer = container;
            }
            //擷取響應資料
            HttpWebResponse response = request.GetResponse() as HttpWebResponse; 
            StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("gb2312"));
            string html = sr.ReadToEnd();
            response.Close();
            txtMsg.Text = html; //txtMsg是文字框

 ---------------------------

 注意,
1.上面代碼是直接從vs2005複製過來的,沒加格式化,方便於直接複製回去,

2.一般的資料擷取下使用WebClient比較方便,也可以一起使用WebClient跟WebRequest.

3.WebRequest.AllowAutoRedirect=false;屬性 來防止自動重新導向

4.WebRequest 想設定Referer 標題時使用 WebRequest.Referer="xxxx" ,直接WebRequest.Headers.Add是不行的
   不過使用webClient時可以這麼做.

5.注意上面的編碼post資料一般要先進行urlEncode,並且指明
 request.ContentType = "application/x-www-form-urlencoded";
 webClient時使用 webClient.Headers.Add("Content-Type","application/x-www-form-urlencode");
 另外在將資料轉化成byte[] data(位元組數組時)請確認網站使用的編碼是utf-8還是gb2312或其他,同樣擷取返會的資料後(指本類型的),也要根據網站的編碼進行轉化(到字串)

 
6.上面使用formdata是虛擬,呵呵,防止你黑了我的站(^_^),你如果要測試,請自己另外找個網站,另外.net表單提交時會有一些狀態資訊,這些你可以通過一向代理工具來擷取,並分析得出需要的post資料格式.

 另外對於帶圖片驗證碼的登入,一般我們在使用WebRequest下載圖片時需要同時儲存下載圖片時的臨時SessionID(也是cookie),在提交表單時要將這個SessionID資料(cookie)附加到標題上,這樣就可以通過驗證,至於圖片識別,一般使用圖片框顯示後人工識別(通用情況下).

參考資料
 HttpWebRequest

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.