2011-10-06 9 views
10

Desidero selezionare un modulo con mechanize. Questo è il mio codice:Python Mechanize seleziona form FormNotFoundError

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

codice del form:

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

Ma sto ottenendo questo errore:

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

risposta

23

Il problema è che il modulo non ha un nome, solo un ID ed è login_form. È possibile utilizzare un predicato:

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

(dove SE se f.attrs ha la chiave id e, in caso affermativo, il valore è pari a idlogin_form). In alternativa, è possibile passare il numero del modulo nella pagina, se si sa se è il primo, il secondo, ecc Ad esempio, la riga sotto seleziona la prima forma:

br.select_form(nr=0) 
1

un po 'più leggibile:

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 

poi:

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

Perché non una funzione come 'def element_by_id (id): il ritorno 'id' in f.attrs e f.attrs [ 'id'] == ' login_form''? – brandizzi

+1

Avevo in mente il funtore C++. Ma come passeresti l'oggetto "f" alla tua funzione? (il predicato ottiene le forme, non gli ID, giusto?). E volevo qualcosa che potessi dare a molti select_form con predicato, ma con id-forma diversa ogni volta (non voglio creare una nuova funzione per ogni form-id) – nivniv