2011-10-06 12 views
10

Quiero seleccionar un formulario con mecanizar. Este es mi código:Python Mecanizar formulario de selección FormNotFoundError

br = mechanize.Browser() 
self.br.open(url) 
br.select_form(name="login_form") 

código del formulario:

<form id="login_form" onsubmit="return Index.login_submit();" method="post" action="index.php?action=login&server_list=1"> 

Pero estoy consiguiendo este error:

mechanize._mechanize.FormNotFoundError: no form matching name 'login_form 

Respuesta

23

El problema es que su forma no tiene un nombre, solo una identificación, y es login_form. Se puede utilizar un predicado:

br.select_form(predicate=lambda f: f.attrs.get('id', None) == 'login_form') 

(donde SE Si f.attrs tiene la clave id y, si es así, el valor es igual a idlogin_form). Alternativamente, se puede pasar el número del formulario en la página, si se sabe si es la primera, la segunda, etc. Por ejemplo, la línea de abajo selecciona la primera forma:

br.select_form(nr=0) 
1

un poco más legible:

class Element_by_id: 
    def __init__(self, id_text): 
     self.id_text = id_text 
    def __call__(self, f, *args, **kwargs): 
     return 'id' in f.attrs and f.attrs['id'] ==self.id_text 

a continuación:

b.select_form(predicate=Element_by_id("login_form")) 
+1

¿por qué no una función como 'def element_by_id (id): return 'id' en f.attrs y f.attrs [ 'id'] == ' login_form''? – brandizzi

+1

Tenía el functor de C++ en mi mente. Pero, ¿cómo pasarías el objeto "f" a tu función? (El predicado obtiene formas, no identificadores, ¿verdad?). Y quería algo que pudiera dar a muchos de tales select_form con predicado, pero con diferente form-id cada vez (no quiero hacer una nueva función para cada formulario-id) – nivniv

Cuestiones relacionadas