2011-02-28 5 views
0

좋아, 제 3자가 운영하는 내부 웹 사이트에서 데이터를 가져 오려고합니다. 게시 방법을 통해 로그인하고 필요한 쿠키를 얻을 수있는 것 같지만 로그인 페이지의 뒤에있는 페이지에 액세스하려고 시도하면 작동하지 않습니다. 여전히 원래 로그인 페이지를 반환합니다. 내가 뭘 잘못하고 있는지 확실하지 않은 코드가 있습니다.로그인 후 웹 페이지에 액세스하려고하면 웹 스크래핑을 수행합니다.

public class FetchData 
{ 
    public static void Main(string[] args) 
    { 
     StringBuilder sb = new StringBuilder(); 

     // used on each read operation 
     byte[] buf = new byte[8192]; 
     HttpWebRequest request = (HttpWebRequest)WebRequest.Create("url_1"); 
     //url behind website login 
     HttpWebRequest request1 = (HttpWebRequest)WebRequest.Create("url_2"); 
     request.Method = "POST"; 
     request.CookieContainer = new CookieContainer(); 
     request1.CookieContainer = new CookieContainer(); 
     string postData = "__VIEWSTATE=%2FwEPDwUKMTE5MDg0MzIzM2QYAQUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgEFCWltYl9sb2dpbgtoYQyQQGMGv%2FcyvjeVOFG%2FhKtH&__EVENTVALIDATION=%2FwEWBAKKxOr4DQK3u5vhBALH%2FIHIDwLy7cL8Avc7%2FoWPCUSNmf%2B6pyue9ytCp6Ki&txt_username=Name&imb_login.x=28&imb_login.y=1&txt_password=password"; 
     byte[] byteArray = Encoding.UTF8.GetBytes(postData); 
     // Set the ContentType property of the WebRequest. 
     request.ContentType = "application/x-www-form-urlencoded"; 
     // Set the ContentLength property of the WebRequest. 
     request.ContentLength = byteArray.Length; 
     request1.ContentLength = byteArray.Length; 
     // Get the request stream. 
     using (Stream dataStream = request.GetRequestStream()) 
     { 
      dataStream.Write(byteArray, 0, byteArray.Length); 
      dataStream.Close(); 
     } 

     HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 

     // Print the properties of each cookie. 
     foreach (Cookie cook in response.Cookies) 
     { 
      Cookie oC = new Cookie(); 

      // Convert between the System.Net.Cookie to a System.Web.HttpCookie... 
      oC.Domain = request.RequestUri.Host; 
      oC.Expires = cook.Expires; 
      oC.Name = cook.Name; 
      oC.Path = cook.Path; 
      oC.Secure = cook.Secure; 
      oC.Value = cook.Value; 

      request1.CookieContainer.Add(oC); 
      Console.WriteLine(oC.ToString()); 
     } 

     response.Close(); 
     response = (HttpWebResponse)request1.GetResponse(); 

     Stream resStream = response.GetResponseStream(); 

     string tempString = null; 
     int count = 0; 

     do 
     { 
      // fill the buffer with data 
      count = resStream.Read(buf, 0, buf.Length); 

      // make sure we read some data 
      if (count != 0) 
      { 
       // translate from bytes to ASCII text 
       tempString = Encoding.ASCII.GetString(buf, 0, count); 

       // continue building the string 
       sb.Append(tempString); 
      } 
     } 
     while (count > 0); // any more data to read? 

     // print out page source 
     Console.WriteLine(sb.ToString()); 
     response.Close(); 

     Console.ReadLine(); 
    } 
} 
+0

더 나은 요청 이름을 사용해야합니다. – SLaks

+0

'StreamWriter'와'StreamReader'를 사용해야합니다. – SLaks

답변

3

두 요청 모두에 동일한 CookieContainer을 넣어야합니다.

그러나 접근 방법에 결함이 있습니다. ASP.Net ViewState 및 EventValidation은 재생할 수 없습니다.

원본 양식을 요청하고 HTML 애자함 팩을 사용하여 양식 요소를 읽고 해당 양식에서 POST를 작성해야합니다.

+0

좋아, 나도 몰랐어. 기회가 생겼을 때 한번 시도 해보지. – Egryan

0

당신의 노력을 해칠 위험이 있으므로 대신 Selenium을 사용하고 C#에서 호출하도록 제안 할 수 있습니까? 진짜 파이어 폭스 브라우저를 만들고 실제로 웹 요청을 실행하기 때문에 저수준의 배관 작업을 많이 처리합니다.

+0

알았어, 그걸 확인하고 끝까지 내 도움 덕분에 만날 수 있는지 알아봐야 겠어. – Egryan

+0

그냥 원한다면 Selenium의 맛, 브라우저 플러그인 버전 인 Selenium IDE를 다운로드하십시오. C#으로 프로그램 할 수는 없지만 Selenium이 무엇인지 이해하는 데 도움이됩니다. –

관련 문제