Python Mechanize select form FormNotFoundError
Asked Answered
E

2

10

I want to select a form with mechanize. This is my code:

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

The form's code:

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

But I'm getting this Error:

mechanize._mechanize.FormNotFoundError: no form matching name 'login_form
Expanse answered 6/10, 2011 at 11:54 Comment(0)
S
24

The problem is that your form does not have a name, only an id, and it is login_form. You can use a predicate:

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

(where you se if f.attrs has the key id and, if so, the id value is equal to login_form). Alternatively, you can pass the number of the form in the page, if you know if it is the first one, the second one etc. For example, the line below selects the first form:

br.select_form(nr=0)
Santo answered 6/10, 2011 at 15:56 Comment(0)
V
1

a little more readable:

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

then:

b.select_form(predicate=Element_by_id("login_form"))
Vanhouten answered 22/2, 2013 at 21:24 Comment(2)
Why not a function such as def element_by_id(id): return 'id' in f.attrs and f.attrs['id'] == 'login_form'?Santo
I had the C++ functor in my mind. But how would you pass the "f" object then to your function? (predicate gets forms, not ids, right?). And I wanted something that I could give to many such select_form's with predicate, but with different form-id each time (I don't want to make a new function for each form-id)Vanhouten

© 2022 - 2024 — McMap. All rights reserved.