2009-04-09 32 views
27

Tengo un script de mecanizado escrito en python que rellena un formulario web y se supone que debe hacer clic en el botón 'crear'. Pero hay un problema, la forma tiene dos botones. Uno para 'agregar archivo adjunto' y otro para 'crear'. Ambos son del tipo 'enviar', y el botón adjuntar es el primero en la lista. Entonces, cuando selecciono el foro y hago br.submit(), hace clic en el botón 'adjuntar' en lugar de 'crear'. Extenso Google no ha producido nada útil para seleccionar un botón específico en un formulario. ¿Alguien sabe de algún método para omitir el primer botón 'enviar' y hacer clic en el segundo?Python mecanizar - dos botones del tipo 'enviar'

Respuesta

21

He intentado usar el parámetro nr, sin ningún tipo de suerte.

que era capaz de conseguir que funcione con una combinación de los parámetros de nombre y de etiquetas, donde "etiqueta" parece corresponder al "valor" en el código HTML:

Aquí están mis dos botones de envío:

<input type="submit" name="Preview" value="Preview" /> 
<input type="submit" name="Create" value="Create New Page" /> 

...y aquí está el código que hace clic en el primero, se remonta, y luego hace clic en el segundo:

from mechanize import Browser 
self.br = Browser() 
self.br.open('http://foo.com/path/to/page.html') 
self.br.select_form(name='my_form') 
self.br['somefieldname'] = 'Foo' 
submit_response = self.br.submit(name='Preview', label='Preview') 
self.br.back() 
self.br.select_form(name='my_form') 
self.br['somefieldname'] = 'Bar' 
submit_response = self.br.submit(name='Create', label='Create New Page') 

Hay una variante que también trabajó para mí, donde el "nombre" del botón de envío es el mismo, tales como :

<input type="submit" name="action" value="Preview" /> 
<input type="submit" name="action" value="Save" /> 
<input type="submit" name="action" value="Cancel" /> 

y

self.br.select_form(name='my_form') 
submit_response = self.br.submit(name='action', label='Preview') 
self.br.back() 
submit_response = self.br.submit(name='action', label='Save') 

NOTA IMPORTANTE - estaba única capaz de conseguir algo de esto en código botones múltiples someterse a trabajar después de limpiando algo de HTML en el resto de la página.

Específicamente, no pude tener <br/> - en cambio tuve que tener <br /> ... y, teniendo aún menos sentido, no pude tener nada entre los dos botones de envío.

Me frustra que no tiene fin de que el error mecanizar/ClientForm me cazado por más de dos horas se reducía a esto:

<tr><td colspan="2"><br/><input type="submit" name="Preview" value="Preview" />&nbsp;<input type="submit" name="Create" value="Create New Page" /></td></tr> 

(todo en una línea) que no funcionó, pero

<tr><td colspan="2"><br /> 
<input type="submit" name="Preview" value="Preview" /> 
<input type="submit" name="Create" value="Create New Page" /></td></tr> 

funcionó bien (en varias líneas, lo que tampoco debería haber importado).

Me gusta mecanizar porque es fácil de instalar (solo copie los archivos en mi directorio de inclusión) y porque es bastante simple de usar, pero a menos que me esté perdiendo algo importante, creo que errores como este son terribles - No puedo pensar en ninguna buena razón por qué el primer ejemplo debería fallar y el segundo debería funcionar.

Y, dicho sea de paso, también encontré otro error mecanizar donde un <textarea> que está contenido dentro de un <p> no se reconoce como un control válido, pero una vez que lo saca del recipiente <p> Es reconocido muy bien. Y lo he comprobado, textarea es permitido para ser incluido en otros elementos de nivel de bloque como <p>.

2

Puedo hablar por experiencia usando HTTP, en lugar de mecanizar, pero creo que esto es probablemente lo que quieres.

Cuando hay dos botones de envío en un formulario, un servidor puede determinar cuál se presionó, porque el cliente debería haber agregado un argumento para el botón Enviar. Por lo tanto:

<form action="blah" method="get"> 
    <p> 
     <input type="submit" name="button_1" value="One" /> 
     <input type="submit" name="button_2" value="Two" /> 
    </p> 
</form> 

que o bien se llevará a la URL:

blah?button_1=One 

o:

blah?button_2=Two 

Dependiendo de lo que se ha pulsado el botón.

Si está determinando mediante programación qué argumentos se van a enviar, debe agregar un argumento con el nombre del botón de envío que se presionó y su valor.

7

Le sugiero que use la tela cruzada que usa el mecanizado (sobre todo monkeypatched). Digamos que tiene formulario con algunos campos y dos botones de envío con nombres "submit_to_preview" y "real_submit". El siguiente código debería funcionar.

BTW recuerde que esto no es seguro para los hilos, por lo que es posible que desee utilizar bloqueos en caso de que desee utilizar el código en un env roscado.

import twill.commands 
b = twill.get_browser() 
url = "http://site/myform" 
twill.commands.go(url) 
twill.commands.fv("2", "name", "Me") 
twill.commands.fv("2", "age", "32") 
twill.commands.fv("2", "comment", "useful article") 
twill.commands.browser.submit("real_submit") 

Espero que ayude. Aclamaciones.

4

Utilice el método 'clic'. P.ej.

mybrowser.select_form(nr=0) 
req = mybrowser.click(type="submit", nr=1) 
mybrowser.open(req) 

Debería funcionar.

Cuestiones relacionadas