2009-07-23 8 views
1

J'essaie de télécharger et d'analyser le code HTML d'une page Web. Récemment, le site Web source est passé d'avoir toutes ses informations sur une page pour en cacher une partie derrière javascript. Il y a une case à cocher "Afficher tout" qui doit être activée pour afficher la page entière.ASP.NET Screen Scrape Post Simuler

Voici le site: Source Website

Essentiellement, je suis à la recherche d'automatiser la récupération après cette page la case à cocher a été cliqué. Actuellement, nous avons un programme C qui télécharge la page Web et gère notre analyse. Je ne suis pas sûr si elle peut accepter javascript dans l'URL si cela peut être utilisé pour résoudre ce problème (j'ai essayé d'utiliser un bookmarklet pour appeler le javascript de l'URL, mais je n'ai pas réussi à l'obtenir pour gérer le case à cocher), mais il peut gérer les fichiers s'il est plus facile d'écrire un programme C# qui peut gérer cela.

Je préférerais un moyen de coder moi-même plutôt que d'utiliser un programme tiers pour éviter d'avoir à installer quoi que ce soit sur le serveur. Toute aide est grandement appréciée.


Edit: En gros, comment puis-je automatiser l'appel au javascript qui est lié à cette « Sélectionner tout » case à cocher Je peux saisir le tout contenant la page html est il est affiché après avoir cliqué sur la case à cocher.


Edit 2: est ici la sortie de Fiddler2:

__EVENTTARGET ctl00$ContentPlaceHolder1$GenericWebUserControl$ShowAllCheckBox 
__EVENTARGUMENT 
__LASTFOCUS 
__VIEWSTATE (REMOVED DUE TO LENGTH) 
__EVENTVALIDATION (REMOVED DUE TO LENGTH) 
ctl00$ContentPlaceHolder1$GenericWebUserControl$Organization0 ALL 
ctl00$ContentPlaceHolder1$GenericWebUserControl$Initial or Amendment1 ALL 
ctl00$ContentPlaceHolder1$GenericWebUserControl$Relief Requested2 ALL 
ctl00$ContentPlaceHolder1$GenericWebUserControl$Country3 ALL 
ctl00$ContentPlaceHolder1$GenericWebUserControl$Status4 ALL 
ctl00$ContentPlaceHolder1$GenericWebUserControl$StartDate5 
ctl00$ContentPlaceHolder1$GenericWebUserControl$EndDate5  
ctl00$ContentPlaceHolder1$GenericWebUserControl$ShowAllCheckBox on 

Je reçois actuellement 500 ERREURS du serveur. Dois-je inclure tous ces GenericWebUserControls dans la demande de publication? Dois-je aussi inclure EVENTVALIDATION?


EDIT 3: Voici le dernier code. Je reçois toujours des erreurs de serveur 500.

private void CreateRequest() 
{ 
    HttpWebRequest httpWebRequest; 
    HttpWebResponse httpWebResponse; 
    StreamWriter streamWriter; 
    Stream webResponseStream; 
    StreamReader streamReader; 
    string postData; 
    string outputHTML; 

    postData = String.Format("&__EVENTTARGET={0}" + "&__VIEWSTATE={1}" + "&__EVENTVALIDATION=(2)"+"&ctl00$ContentPlaceHolder1$GenericWebUserControl$ShowAllCheckBox=on" +"&ctl00$ContentPlaceHolder1$GenericWebUserControl$Organization0=ALL" +"&ctl00$ContentPlaceHolder1$GenericWebUserControl$Initial+or+Amendment1=ALL" +"&ctl00$ContentPlaceHolder1$GenericWebUserControl$Relief+Requested2=ALL" +"&ctl00$ContentPlaceHolder1$GenericWebUserControl$Country3=ALL" +"&ctl00$ContentPlaceHolder1$GenericWebUserControl$Status4=ALL",EVENTTARGET, VIEWSTATE, EVENTVALIDATION); 

    httpWebRequest = (HttpWebRequest)WebRequest.Create("http://services.cftc.gov/sirt/sirt.aspx?Topic=ForeignPart30Exemptions"); 
    httpWebRequest.Method = "POST"; 
    httpWebRequest.ContentType = "application/x-www-form-urlencoded"; 
    httpWebRequest.ContentLength = postData.Length; 

    streamWriter = new StreamWriter(httpWebRequest.GetRequestStream(), System.Text.Encoding.ASCII); 
    streamWriter.Write(postData); 
    streamWriter.Close(); 

    httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse(); 

    webResponseStream = httpWebResponse.GetResponseStream(); 
    streamReader = new StreamReader(webResponseStream); 
    outputHTML = streamReader.ReadToEnd(); 

    Console.WriteLine(outputHTML); 
} 

EDIT 4: J'ai déterminé que c'est la chaîne postData qui cause l'erreur serveur 500. Si j'en fais une chaîne vide, elle affiche la page Web entière. Est-ce que quelqu'un sait si j'ai raison de mettre tout ce qui vient de Fiddler2 qui a une valeur dans la chaîne postData? En outre, que __VIEWSTATE est une chaîne incroyablement longue. Y a-t-il des limites ou quelque chose dont je ne suis pas sûr?


EDIT 5: j'ai couru toutes les chaînes utilisées dans postData par un codeur URL, mais je suis encore en train serveur 500 erreurs. Y at-il un moyen pour moi de déboguer pourquoi ce corps de poste est invalide?


SOLUTION: Ok, je ne pouvais pas obtenir ma chaîne postData correcte, mais quand je collais dans le corps brut POST il fonctionne. Cela semble être assez bon, mais je me demande si cela va continuer à fonctionner.

+1

Pouvez-vous formuler une question? –

Répondre

3

C'est une page asp.net.Si vous cliquez sur la case à cocher, la page est renvoyée au serveur. Donc, plutôt que d'essayer de simuler le javascript, ce que vous voulez faire est de simuler la demande de publication.

Ceci est notoirement difficile avec les pages ASP.Net, car vous devez généralement remplir l'entrée __ViewState masquée. Je recommande d'utiliser un renifleur de paquets comme Fiddler pour voir la demande réelle telle qu'elle est envoyée. Vous devriez être capable de copier le ViewState à partir de là.

+0

Ok, alors j'ai lancé le sniffer et je suis allé à l'entrée ViewState. Je suppose que je peux maintenant lancer un C# HttpWebRequest maintenant pour simuler la demande de publication. La seule autre question que j'ai est que ViewState changera jamais? –

+0

Il pourrait. ViewState peut stocker des choses comme des jetons d'utilisateur, des chapelures, etc. Vous pouvez mettre beaucoup de choses là-dedans. Mais la principale chose qui vous intéresse est qu'elle soit 'valide' dans le cas où EnableEventValidation est défini sur true (par défaut) et que votre entrée de case à cocher a la valeur correcte. –

+0

Une idée de pourquoi j'obtiendrais des erreurs de serveur 500? Je suppose que quelque chose ne va pas avec le mécanisme de poste. –

1

Il semble que le JavaScript initie un POST à ​​la même page. Firebug affiche les éléments suivants dans les données POST.

__EVENTTARGET: ctl00$ContentPlaceHolder1$GenericWebUserControl$ShowAllCheckBox 

C'est probablement un bon point de départ.

+0

Donc, je peux le faire en utilisant une méthode C# HttpWebRequest POST? Je ne suis pas vraiment familier avec la programmation web. Devrai-je utiliser l'approche de reniflage de paquets pour obtenir l'information dont j'ai besoin? –

+0

Firebug fonctionnerait aussi, mais il y a beaucoup de javascript à suivre. Vous avez juste besoin de _something_ qui vous montrera quelles données sont finalement publiées sur le serveur, de sorte que vous pouvez simuler la même requête. –