2015-07-21 19 views
11

Bu biraz uzunca sarılmış açıklama için benimle lütfen benimle karşılaşıyorum ama bir ASP.NET web formları sayfası kazıma C# ekran ile garip bir sorun yaşıyorum. Yapmaya çalıştığım adımlar şu şekildedir: -C# ekran bir ASP.NET web formları sayfa kazıma - POST isteği tamamen çalışmıyor

1) Site, HTTPS üzerinden temel kimlik doğrulaması kullanılarak güvenceye alınmıştır, bu yüzden uygun şekilde giriş yapmam gerekiyor. Bu şeyi ayarlamak kalmazsam __VIEWSTATE değerini almak için sayfada bir GET isteği sahnede oluyorum

2) (lanetlemek şey hiçbir şey yapmaz!)

3) Bir kere açmış birkaç form alanı yok içinde sonra POST formun sunucuya göndereceği bir gönderme düğmesini tamamlamak için

) Gönderme düğmesine basıldığında, form sunucuya POST'tur ve yanıt aynı sayfa ve formdur ancak artık ekstra bir HTML tablosuyla birlikte olur formun alt kısmında, almam gereken bazı veriler var.

WebClient sınıfını kullanarak giriş ve form defterini sıralamayı çoktan başardım. Normalde bir tarayıcı kullanarak formu doldururken gönderilen POST alan değerlerini kontrol etmek için kemancı (ve firebug) kullandım. POST isteğinden, beklenen şekilde formun altında görünen söz konusu veri tablosuyla bir yanıtı başarılı bir şekilde alabilirim. Ancak sorun şu ki tablo verilerle doldurulmuş olsa da beklemediğim verilerle dolu. Görünen veriler, formu normal olarak ancak belirli bir parametrede (bir açılır liste) POST isteğimden sunucuya geçirdiğimden farklı bir değere ayarlanmış olsaydım, formdaki bir tarayıcıda tamamladım. Bir kullanıcı tarafından tamamlanmış bir web tarayıcısı kullanılarak normal olarak gönderilen aynı POST parametrelerini iletiyorum kemancı ve firebug kullanarak onayladı. Şimdi bu parametrenin neden sunucu tarafından 'dikkate alınmadığı' konusunda sıkışıp kaldım?

Tek fark, bu özel denetimin bir seçim listesi olmasıdır ve değiştirildiğinde bir sayfa yeniden yükleme veya 'geri gönderme' gerçekleştirir. Ancak bu, formdaki diğer bazı seçim listelerini değiştirmek dışında bir şey yapmıyor gibi görünüyor.

Sanırım soruyorum ki, buna neden olan başka bir şey var mı? Bu saçlarımı tamamen yırtıyorum. Biri yardım edebilir mi? Aşağıdaki kodu yayınladım (adresler ve gizlilik için boş bırakılmış parametreler).

// a place to store the html 
    string responseBody = ""; 

    // create out web client to handle the request 
    using (WebClient webClient = new WebClient()) 
    { 
     // space to store responses from the remote site 
     byte[] responseBytes; 

     // site uses basic authentication over HTTPS so we'll need to login 
     CredentialCache credentials = new CredentialCache(); 
     credentials.Add(new Uri(Url), "Basic", new NetworkCredential(Username, Password)); 

     // set the credentials in the web client 
     webClient.Credentials = credentials; 

     // a place for __VIEWSTATE 
     string viewState = ""; 

     // try and get __VIEWSTATE from the web site 
     try 
     { 
      responseBytes = webClient.DownloadData(Url); 
      viewState = GetHtmlInputValue(Encoding.UTF8.GetString(responseBytes), "__VIEWSTATE"); 
     } 
     catch (Exception e) 
     { 
      bool cancel = false; 
      ComponentMetaData.FireError(10, "Read web page data", "Error whilst trying to get __VIEWSTATE from web page: " + e.Message, "", 0, out cancel); 
     } 

     // add our POST parameters (don't forget the __VIEWSTATE or it won't work as its an ASP.NET web page) 
     NameValueCollection requestParameters = new NameValueCollection(); 

     // add ASP.NET fields 
     requestParameters.Add("__EVENTTARGET", __EVENTTARGET); 
     requestParameters.Add("__EVENTARGUMENT", __EVENTARGUMENT); 
     requestParameters.Add("__LASTFOCUS", __LASTFOCUS); 

     // add __VIEWSTATE 
     requestParameters.Add("__VIEWSTATE", viewState); 

     // all other form parameters 
     requestParameters.Add("btnSubmit", btnSubmit);  
     /* I've hidden the rest of the parameters hidden for privacy just in case */ 

     // see if we can connect and get data 
     try 
     { 
      // set content type 
      webClient.Headers.Clear(); 
      webClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded");        

      // 'POST' the form data using web client and hope we get a response 
      responseBytes = webClient.UploadValues(Url, "POST", requestParameters); 

      // transform the response to a string 
      responseBody = Encoding.UTF8.GetString(responseBytes); 
     } 
     catch (Exception e) 
     { 
      bool cancel = false; 
      ComponentMetaData.FireError(10, "Read web page data", "Error whilst trying to connect to web page: " + e.Message, "", 0, out cancel); 
     } 
    } 

SSIS komut dosyasının bir parçası olduğu için 'ComponentMetaData' başvurularını dikkate almayın.

Herhangi bir fikir veya yardım büyük takdir edilecektir - şerefe!

RE: Hızlı yanıtlar için teşekkürler, tüm O yorumlarına söyleyebiliriz olduğunu ...

Normal ASP oturum tanımlama var ama hiçbir değerleri (dışında elbette oturum kimliği itibaren) çerezinde var

, Ben site temel kimlik doğrulama değil formları kimlik doğrulama kullanıyordum düşündüm Ben sadece göz ardı edilebilir - ve siteye girerken ve veri alma bu ok tamam ben iade. Sanırım bir denemeye değer ama bunun yerine WebRequest sınıf metodunu kullanmak için kodu değiştirmem gerekecek ...

Seçim listesi javascript için, sayfadan sonra seçim listesinin değerini değiştiren herhangi bir javascript yok. yük. Seçim listesindeki tek javascript, bir 'geri gönderme' yapmak için bir onchange olayıdır, bu sadece son POST'ta boş olan formdaki diğer bazı seçme listelerini değiştiriyor gibi görünür. Not POST isteğini oluştururken tüm POST parametrelerini boş bırakıyor olsa bile ekliyorum ve aynı zamanda __VIEWSTATE, __EVENTTARGET vb. Gibi tüm 'web formları' özel alanlarını da dahil ediyorum.

Web formlarında uzman değilim (MVC man kendim), ancak web'in 'motor' oluşturduğu başka bir şey var mı? 'Application/x-www-form-urlencoded' in 'Content-Type' için 1 başlık gönderdim ama 'User-Agent' başlığını orijinal POST'tan kopyalamak gibi diğerlerini ayarlamayı denedim ama bu sonuçta sona erdi Benimle sunucudan 500 hata alıyorum, bunun neden olacağından emin değil misiniz? İşte

onun biraz basit/temel ve daha iyi yapılabilirdi ama 'GetHtmlInputValue' kod şöyledir: -

private string GetHtmlInputValue(string html, string inputID) 
    { 
     string valueDelimiter = "value=\""; 

     int namePosition = html.IndexOf(inputID); 
     int valuePosition = html.IndexOf(valueDelimiter, namePosition); 

     int startPosition = valuePosition + valueDelimiter.Length; 
     int endPosition = html.IndexOf("\"", startPosition); 

     return html.Substring(startPosition, endPosition - startPosition); 
    } 
+0

Tarayıcınızda herhangi bir çerez var mı? Bunları isteğinize eklemeniz gerekebilir. – NibblyPig

+1

Sayfa yüklendikten sonra select kutusunun değeri javascript ile ayarlanmış mı kontrol ettiniz mi? Bu, beklediğinizden neden farklı olduğunu açıklayabilir. – Engin

+0

Giriş denetimlerinin değerlerini iletmek için webClient.AppendUploadString (PostFieldName, PostFieldValue) 'yi kullanmaya çalıştınız mı? –

cevap

0

Sonra bir POST neden olur açılır listedeki öğe seçme doğru anlamak gerçekleştirilecek ve sunucu formun başka bir bölümünde kullanılabilir seçenekleri değiştirir. Sunucu, daha sonra açılır menünün geçerli değerini __VIEWSTATE alan değerine dahil edecektir.

Kazıma işlemini gerçekleştirdiğinizde, __VIEWSTATE'un açılır menü için istenen değeri içerdiğinden emin olmalısınız. Daha fazla araştırmak için sunucudan decode the viewstate'u deneyin ve hangi değerlerin geri gönderildiğini görün.

+0

gönderdim Bu kadar, sadece 'GET' isteği kullanarak ilk __VIEWSTATE alma bahsetti 'web formları' öğreticiler formu tüm formu vardı. dürüst olmak gerekirse, __VIEWSTATE'de kodlama yapmaktaydım, gerçekten gerçekten __VIEWSTATE'in gerçekten ne yaptığını bilmiyordum.Ayrıca, form değerleri gönderdikten sonra değiştirilen görünümleri almak için kodumu güncelledim ve sonra güncellenmiş görünüm ve Çok teşekkürler, çok fazla kafa çizdi, – padigan

+0

Rica ederim :) –

İlgili konular