Autor
|
Tema: enviar datos con WebRequest (Leído 9,390 veces)
|
s_azazel
Desconectado
Mensajes: 98
|
Buenas tardes!!! estoy intentando automatizar un registro. tengo algo en phyton pero me gustaria pasarlo a vb.net porque me siento mas comodo en phyton pido info de una url enviandole unos datos: a=requests.get(url) data={'idDepartamento':'1','idServicio':'1','idTramite':'22','idAsunto':'42'}
e=requests.post(url,data=data) Y en vb.net tengo algo asi: Dim request As System.Net.HttpWebRequest = System.Net.HttpWebRequest.Create("URL") request.CookieContainer = New CookieContainer() Dim response As System.Net.HttpWebResponse = request.GetResponse() El codigo de la pagina me lo devuelve perfectamente pero no encuento la forma de enviar con el request los datos ({'idDepartamento':'1','idServicio':'1','idTramite':'22','idAsunto':'42'}) Que envio con phyton Gracias!!!
|
|
|
En línea
|
|
|
|
kub0x
Enlightenment Seeker
Moderador
Desconectado
Mensajes: 1.486
S3C M4NI4C
|
Buenas s_azazel, por lo que veo quieres enviar una ristra de parámetros por POST a un apartado de registro específico en un servidor web. En Python parece bastante intuitivo, en .NET también lo es, sin necesidad de tener que lidiar con APIs molestas, ya que el Framework (conjunto de clases, librerias etc) nos aporta un nivel aceptable de abstración. Si tienes FireFox con la extensión de FireBug podrás analizar las cabeceras de los paquetes que envias en todo momento, pudiendo analizar el paquete que envias a dicho apartado de registro. Ahí lo dejo caer... Te dejo un ejemplo de como enviar datos por POST, puede que haya algo mal ya que lo he escrito del tirón: Dim request As HttpWebRequest = CType(HttpWebRequest.Create(URL), HttpWebRequest) With request 'El UserAgent es el que utiliza mi navegador, pon aqui uno cualquiera .UserAgent = "Mozilla/5.0 (Windows NT 6.1; rv:22.0) Gecko/20130315 Firefox/22.0" .Proxy = Nothing .Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" .Method = "POST" .ContentType = "application/x-www-form-urlencoded" .ContentLength = Data.Length 'Donde data son los datos que quieres enviar IdDepartamento, IdServicio... End With 'Llegados a este punto ya hemos configurado las cabeceras del paquete Http que vamos a enviar por POST 'Ahora solo falta escribir esos datos en el paquete que queremos enviar Using requestStream As Stream = req.GetRequestStream() requestStream.Write(data, 0, data.Length) requestStream.Close() End Using 'Hemos terminado de escribir los datos en el paquete, ahora solo falta enviarlo y recibir la respuesta Dim response As HttpWebResponse = req.GetResponse() '...... y aquí lo que necesites
Un saludo!
|
|
|
En línea
|
|
|
|
Eleкtro
Ex-Staff
Conectado
Mensajes: 9.878
|
Kubox, tengo la sensación de que el código lo escribiste al vuelo (porque no tiene indentación), te equivocaste al escribir un par de cosas, el nombre del objeto que usas es 'request', pero luego lo escribes como 'req', también el Stream espera un array de bytes pero le estás pasando un String a secas (Data) , pero vamos, creo que se entiende perféctamente lo que quisiste explicar, son cosas sin importancia pero... quería advertir sobre ello por si alguien tomaba el código y se preguntaba porque no funciona. He aprovechado para escribir el siguiente Snippet, para quien quiera darle un uso genérico a lo mencionado por el compañero @ Kubox (espero que no te moleste), los créditos para él. ''' <summary> ''' Sends a POST method petition and returns the server response. ''' </summary> ''' <param name="URL">Indicates the URL.</param> ''' <param name="PostData">Indicates the post data.</param> ''' <returns>The response.</returns> Public Function SendPOST(ByVal URL As String, ByVal PostData As Dictionary(Of String, String)) As String Dim Data As New System.Text.StringBuilder ' PostData to send, formated. Dim Request As Net.HttpWebRequest = HttpWebRequest.Create(URL) ' HTTP Request. Dim Response As HttpWebResponse ' Server response. Dim ResponseContent As String ' Server response result. ' Set and format the post data of the query. For Each Item As KeyValuePair(Of String, String) In PostData Data.AppendFormat("{0}={1}&", Item.Key, Item.Value) Next Item ' Set the Request properties. With Request .Method = "POST" .ContentType = "application/x-www-form-urlencoded" .ContentLength = Data.ToString.Length .Proxy = Nothing ' .UserAgent = "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0" End With ' Write the POST data bytes into the Stream. Using RequestStream As IO.Stream = Request.GetRequestStream() RequestStream.Write(System.Text.Encoding.UTF8.GetBytes(Data.ToString), 0, Data.ToString.Length) End Using ' Get the response. Response = Request.GetResponse() ' Get the response content. Using Reader As New System.IO.StreamReader(Request.GetResponse().GetResponseStream) ResponseContent = Reader.ReadToEnd Response.Close() End Using ' Return the response content. Return ResponseContent End Function
Ejemplo de uso: Private Sub Test() Handles MyBase.Shown Dim Url As New Uri("http://es.wikipedia.org/wiki/Special:Search?") Dim PostData As New Dictionary(Of String, String) From { {"search", "Petición+POST"}, {"sourceid", "Mozilla-search"} } ' Formated Result: "search=Petición+POST&sourceid=Mozilla-search" Dim Response As String = SendPOST(Url.AbsoluteUri, PostData) Clipboard.SetText(Response) ' Copy to clipboard. MessageBox.Show(Response) End Sub
Saludos!
|
|
« Última modificación: 10 Marzo 2014, 01:18 am por Eleкtro »
|
En línea
|
|
|
|
s_azazel
Desconectado
Mensajes: 98
|
Mil gracias a los dos!!! Me ha funcionado perfectamente
|
|
|
En línea
|
|
|
|
s_azazel
Desconectado
Mensajes: 98
|
No se si esto lo deberia de preguntar aqui...
La idea de le programa es porque en la web que me quiero registrar solo abren los registros una vez cada 15 dias y se acaban en unos 5 o 10 minutos
Durante este tiempo el server se cae varias veces e incluso me ha tardado en cargar una pagina mas de 5 minutos
Asi que habia pensado poner un timeout con un retry cada 10 seg o asi
La pregunta es: ¿se podria hacer mediante HttpWebRequest mas de una peticion de vez para asegurarme que al menos acepte una??
Gracias!!!
|
|
|
En línea
|
|
|
|
Eleкtro
Ex-Staff
Conectado
Mensajes: 9.878
|
Kubox sabe más sobre este tema que yo, pero si la página no te carga... creo que sería una tontería hacer peticiones simultaneas desde la misma IP ya que ninguna te cargaría, creo. De todas formas, poder se puede, puedes usar el método HttpWebRequest.BeginGetResponse, que es asíncrono, pero también podrías enviar una única petición y esperar hasta que se realice corréctamente con un Do Until/While NotEl siguiente Snippet lo escribí hace mucho tiempo, se puede mejorar, pero siempre me ha funcionado bien, pruébalo. ''' <summary> ''' Determines whether a connectivity to an URL is avaliable. ''' </summary> ''' <param name="url">Indicates the URL.</param> ''' <param name="RetryInterval"> ''' Indicates the retry interval, in seconds. ''' Use "-1" to any interval.</param> ''' <param name="StatusControl"> ''' Indicates the status control. ''' If any control is specified, the status will be shown in Debug console. ''' </param> ''' <returns><c>true</c> if connectivity avaliable; otherwise, <c>false</c>.</returns> Private Function IsConnectivityAvaliable(ByVal url As String, Optional ByVal RetryInterval As Integer = -1, Optional ByVal StatusControl As Control = Nothing) As Boolean Dim NoNetworkMessage As String = "Network connection is not avaliable." Dim NoWebsiteMessage As String = "WebSite is not avaliable." Dim NoNetworkRetryMessage As String = "Network connection is not avaliable, retrying in {0} seconds..." Dim NoWebsiteRetryMessage As String = "WebSite is not avaliable, retrying in {0} seconds..." Dim YesNetworkMessage As String = "Network connection established." Dim YesWebsiteMessage As String = "WebSite connection established." Select Case My.Computer.Network.IsAvailable Case False ' No network device avaliable If RetryInterval = -1 Then ' Do not retry PrintNetworkStatus(NoNetworkMessage, StatusControl) Return False Else ' Retry For X As Integer = 0 To RetryInterval WaitNetworkStatus() PrintNetworkStatus(String.Format(NoNetworkRetryMessage, RetryInterval - X), StatusControl) Next X IsConnectivityAvaliable(url, RetryInterval, StatusControl) End If ' RetryInterval Case True ' Network device is avaliable ' Inform that network device is avaliable. PrintNetworkStatus(YesNetworkMessage, StatusControl) Try ' Try connect to the given url My.Computer.Network.Ping(url) ' Inform that Website connection is avaliable. PrintNetworkStatus(YesWebsiteMessage, StatusControl) Return True Catch ex As Net.NetworkInformation.PingException If RetryInterval = -1 Then ' Do not retry PrintNetworkStatus(NoWebsiteMessage, StatusControl) Return False Else ' Retry For X As Integer = 0 To RetryInterval WaitNetworkStatus() PrintNetworkStatus(String.Format(NoWebsiteRetryMessage, RetryInterval - X), StatusControl) Next X IsConnectivityAvaliable(url, RetryInterval, StatusControl) End If ' RetryInterval Catch ex As InvalidOperationException If RetryInterval = -1 Then ' Do not retry PrintNetworkStatus(NoNetworkMessage, StatusControl) Return False Else ' Retry For X As Integer = 0 To RetryInterval WaitNetworkStatus() PrintNetworkStatus(String.Format(NoNetworkRetryMessage, RetryInterval - X), StatusControl) Next IsConnectivityAvaliable(url, RetryInterval, StatusControl) End If ' RetryInterval End Try End Select End Function ''' <summary> ''' Prints the network status. ''' </summary> ''' <param name="Message">Indicates the Status message.</param> ''' <param name="StatusControl">Indicates the control to print the connection Status.</param> Private Sub PrintNetworkStatus(ByVal Message As String, Optional ByVal StatusControl As Control = Nothing) If StatusControl IsNot Nothing Then StatusControl.Invoke(Sub() StatusControl.Text = Message) Else End If End Sub ''' <summary> ''' Waits an interval before trying to reconnect. ''' </summary> ''' <param name="WaitPeriod">Indicates the wait interval, in ms.</param> Private Sub WaitNetworkStatus(Optional ByVal WaitPeriod As Integer = 1000) Threading.Thread.Sleep(WaitPeriod) End Sub
Ejemplo de uso: Private Sub Test() Handles MyBase.Load Dim t As New Threading.Thread(AddressOf CheckConnectivity) t.Start() End Sub Private Sub CheckConnectivity() Do Until IsConnectivityAvaliable("sqwertyqwertyqwerty.com", 10, Label1) Application.DoEvents() Loop ' Enviar POST aquí... End Sub
Saludos
|
|
|
En línea
|
|
|
|
s_azazel
Desconectado
Mensajes: 98
|
Muchas gracias!!! lo tengo ya preparado y con varias el intento de varias conexiones simultaneas
Cuando lo ahaci con el navegador se quedaba colgado hasta 5 minutos o mas hasta que abria la pagina en el momento de el colapso
¿Sabeis si es mejor poner un timeout bajo y refrescar o dejarlo que acabe de cargar (no se si todo ese rato esta cargado algo.La verdad es que es ligerisima la pagina)
El mayor problema es ese pues las citas disponibles se acaban enseguida
Gracias
|
|
|
En línea
|
|
|
|
kub0x
Enlightenment Seeker
Moderador
Desconectado
Mensajes: 1.486
S3C M4NI4C
|
Si no sabes que día ni a que hora exacta va a ser abierto el servidor de registro entonces te recomiendo que montes una aplicación que realice checkeos a la dirección de dicho servidor cada poco tiempo. Cuando detecte que el servidor está activo entonces debería de enviar la petición, siendo uno de los primeros en realizarla. No sé si habrá más bots en juego en dicho momento, ya que no conozco la página contra la que intentas autenticarte, puede que no tengas problemas, o puede que sí.
Para poner el timeout debes pensar en cuanto tiempo tarda el servidor de la página en procesar tu registro, ya que si pones un timeout más bajo cortará la conexión.
Hay varías formas de enviar peticiones a servidores web, una es haciendo uso de hilos, otra es utilizando Tasks (.NET Framework 4.5 creo) y la mejor para mí es haciendo uso de CallBacks, que es uno de los fuertes de .NET. No es más que programación asíncrona, bellísima por cierto.
Cuidado no acabes haciendo un DDoS jajajajajaja, suerte!
Saludos!
|
|
|
En línea
|
|
|
|
s_azazel
Desconectado
Mensajes: 98
|
Muchas gracias!!! Lo he hecho a traves de hilos. Se que abre un viernes de cada dos a las 9 am Tengo ya mas o menos acabado tiene que pasar por dos paginas por temas de cookies, finalmente hace un get a la captcha y envia los datos al formulario
intentare cunado lo abran crear unos 20 hilos a ver si lo agunata
Muchas Gracias!!!!
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Como enviar los datos a la Base de Datos
« 1 2 »
PHP
|
giagete
|
17
|
7,839
|
7 Septiembre 2007, 16:06 pm
por JUCA
|
|
|
¿Qué es un HTTPWEBREQUEST / WEBREQUEST?
.NET (C#, VB.NET, ASP)
|
avmiitxe
|
4
|
5,071
|
18 Abril 2012, 17:31 pm
por avmiitxe
|
|
|
Enviar y Solicitar datos en Base de Datos mediante Winsock?
Programación Visual Basic
|
Brian1511
|
0
|
2,367
|
25 Noviembre 2012, 18:42 pm
por Brian1511
|
|
|
Ayuda p listar datos de base de datos y usar el valor para enviar a otra pagina
PHP
|
daciocco
|
1
|
2,988
|
31 Diciembre 2013, 16:26 pm
por #!drvy
|
|
|
problema con split y webrequest
.NET (C#, VB.NET, ASP)
|
snakeboy8
|
4
|
3,105
|
4 Marzo 2015, 12:13 pm
por snakeboy8
|
|