2009-06-09 12 views
5

Soy muy nuevo en Perl y estoy aprendiendo sobre la marcha mientras trato de automatizar algunos proyectos para el trabajo. Hasta ahora ha sido muy divertido.¿Cómo uso y debo depurar WWW :: Mechanize?

Estoy trabajando para generar un informe para un cliente. Puedo obtener este informe de una página web a la que puedo acceder. Primero tendré que completar un formulario con mi nombre de usuario, contraseña y elegir un servidor de una lista desplegable e iniciar sesión. En segundo lugar, necesito hacer clic en un enlace para acceder a la sección del informe. En tercer lugar, es necesario completar un formulario para crear el informe.

Esto es lo que he escrito hasta ahora:

my $mech = WWW::Mechanize->new(); 
my $url = 'http://X.X.X.X/Console/login/login.aspx'; 

$mech->get($url); 

$mech->submit_form(
    form_number => 1, 
    fields  =>{ 
     'ctl00$ctl00$cphVeriCentre$cphLogin$txtUser' => 'someone', 
     'ctl00$ctl00$cphVeriCentre$cphLogin$txtPW' => '12345', 
     'ctl00$ctl00$cphVeriCentre$cphLogin$ddlServers' => 'Live', 
    button => 'Sign-In' 
    }, 
); 
die unless ($mech->success); 

$mech->dump_forms(); 

yo no entiendo por qué, pero, después de esto Miro el que volcar salidas y veo el código para la primera página de inicio de sesión, mientras que I belive i debería haber llegado a la página siguiente después de mi inicio de sesión exitoso.

¿Podría haber algo con una cookie que me pueda afectar y el intento de inicio de sesión?

¿Algo más que estoy haciendo mal?

Apreciar ayudas, Yaniv

Respuesta

2

Sólo se puede mecanizar el material que ya sabe. Antes de escribir más código, le sugiero que use una herramienta como Firebug e inspeccione lo que está sucediendo en su navegador cuando lo hace manualmente.

Por supuesto, puede haber cookies que se utilizan. ¿O tal vez olvidó un parámetro de formulario oculto? Solo tú puedes decirlo.

EDIT:

  • WWW :: Mecanizar debe hacerse cargo de las galletas sin ninguna intervención adicional.
  • Siempre debe verificar si los métodos que llamó fueron exitosos. ¿Funciona el primer get()?
  • Puede ser útil echar un vistazo a los registros del servidor para ver qué se solicita realmente y qué código de estado HTTP se envía como respuesta.
+0

Thanx Manni. Tengo Firebug, pero no estoy seguro exactamente qué buscar. ¿Dónde busco las cookies? Miré todos los parámetros y no hay ninguno oculto. –

+0

Mire la pestaña con la etiqueta "Net". Revelará todos los encabezados HTTP enviados por el servidor, incluidas las cookies. – innaM

+0

Esto es lo que obtuve de mi código: GET http: //XXXX/Console/login/login.aspx Accept-Encoding: gzip, x-gzip, desinfle User-Agent: libwww-perl/5.822 (sin contenido) HTTP/1.1 200 OK Cache-control: privado Connection: close Fecha: lunes, 08 de Jun 2009 15:08:32 GMT servidor: Microsoft-IIS/6.0 Content-Length: 14720 Content Tipo: text/html; charset = utf-8 Cliente-Fecha: Lun, 08 de junio de 2009 15:08:32 GMT Cliente-Peer: X.X.X.X: 80 Número de respuesta del cliente: 1 –

6

Esto es varios meses después del hecho, pero resolví el mismo problema en base a una pregunta similar que hice. Ver Is it possible to automate postback from the client side? para más información.

Usé Python's Mechanize en su lugar o Perl, pero aplica el mismo principio.

Resumiendo mi respuesta anterior:

páginas ASP.NET necesitan un parámetro oculto llamado __EVENTTARGET en la forma, que no existirá cuando se utiliza normalmente mecanizar.

Cuando es visitado por un usuario normal, hay una función __doPostBack ('foo') en estas páginas que le da el valor relevante a __EVENTTARGET a través de un evento javascript onclick en cada uno de los enlaces, pero mecanize no usa javascript deberá establecer estos valores usted mismo.

La solución de python está por debajo, pero no debería ser demasiado difícil adaptarla a perl.

def add_event_target(form, target): 
    #Creates a new __EVENTTARGET control and adds the value specified 
    #.NET doesn't generate this in mechanize for some reason -- suspect maybe is 
    #normally generated by javascript or some useragent thing? 
    form.new_control('hidden','__EVENTTARGET',attrs = dict(name='__EVENTTARGET')) 
    form.set_all_readonly(False) 
    form["__EVENTTARGET"] = target 
+0

Intenté esto pero para mi problema todavía no funciona. Firebug mostró que también se aprobó otro param (__EVENTARGUMENT). Agregué tanto eso como el __EVENTTARGET, pero parece que se ignoran. Siempre obtengo los mismos resultados (los necesito para la búsqueda, accediendo a las páginas siguientes). –

+0

@HD: ¿Llegaste a tu página mediante un envío de formulario? (Por ejemplo, una función de "Búsqueda de widgets" que le proporcionó una lista de resultados paginados). Si llegó a la página usando un formulario, podría ser mucho más complicado ya que también tendrá que lidiar con esa __VIEWSTATE larga. Si pudieras enviar un enlace, podría darle un vistazo – anschauung

+0

@HD: También encontré en algunos sitios que también debes eliminar algunos valores de formularios extraños. Puede ver todos los valores de campo usando select_form y purgarlos por cualquier medio que su idioma preferido use para eliminar elementos de la matriz. (por ejemplo, .pop() en python) Lamentablemente, la única forma en que he encontrado estos elementos es por prueba y error. – anschauung

0

La esencia de muy corto aspx páginas de TI que tienen toda la información de la sesión local dentro de un par de variables con el prefijo "__" en el aspxform general. Por lo general, este es un formulario de nivel superior y todos los elementos del formulario serán parte de él, pero supongo que puede variar según la implementación.

Para la implementación particular que estaba tratando con que tenía que preocuparse de 2 de estas variables de estado, específicamente:

__VIEWSTATE 
__EVENTVALIDATION. 

Su objetivo es asegurarse de que estas variables se presentan en la forma que está presentando, ya que podrían ser parte de la forma principal aspxform que mencioné anteriormente, y probablemente estés enviando una forma diferente a esa.

Cuando un navegador carga una página aspx, un trozo de javascript pasa esta información de sesión junto con la interacción servidor asp/cliente, pero por supuesto no tenemos ese lujo con Perl Mechanize, por lo que tendrá que publicar manualmente estos usted mismo agregando los elementos a la forma actual usando mecanizar.

En el caso de que me acabo de resolver básicamente hice esto:

my $browser = WWW::Mechanize->new(); 

# fetch the login page to get the initial session variables 
my $login_page = 'http://www.example.com/login.aspx'; 
$response = $browser->get($login_page); 

# very short way to find the fields so you can add them to your post 
$viewstate = ($browser->find_all_inputs(type => 'hidden', name => '__VIEWSTATE'))[0]->value; 
$validation = ($browser->find_all_inputs(type => 'hidden', name => '__EVENTVALIDATION'))[0]->value; 

# post back the formdata you need along with the session variables 
$browser->post($login_page, [ username => 'user', password => 'password, __VIEWSTATE => $viewstate, __EVENTVALIDATION => $validation ]); 

# finally get back the content and make sure it looks right 
print $response->content(); 
2

Si está en Windows, utilice Fiddler a consultar los datos que se está enviando al realizar este proceso de forma manual, y luego utilizar Fiddler para compárelo con los datos capturados cuando lo realiza su secuencia de comandos.

En mi experiencia, un proxy de depuración web como Fiddler es más útil que Firebug al inspeccionar publicaciones de formularios.

1

He encontrado que es muy útil utilizar la utilidad Wireshark al escribir automatización web con WWW::Mechanize. Le ayudará de varias maneras:

  1. Le permite saber si su solicitud HTTP fue exitosa o no.
  2. Consulte el motivo de la falla en el nivel HTTP.
  3. Rastrea los datos exactos que pasas al servidor y mira lo que recibes.

Simplemente configure un filtro HTTP para el tráfico de red y comience su secuencia de comandos de Perl.

Cuestiones relacionadas