0

Trying to use mechanize in Python, I am stucked because the fields I am trying to submit don't have names.

On the mechanize tutorial, it is said:

br.select_form(name="order")
# Browser passes through unknown attributes (including methods)
# to the selected HTMLForm.
br["cheeses"] = ["mozzarella", "caerphilly"]  # (the method here is __setitem__)

This is fine, but in my case the controls don't have name. Here is the code I run to ensure that:

resp = br.open("http://www.facebook.com/find-friends/browser/")
forms = ParseResponse(resp)
form = forms[2]  # I know I have to select form 2
for control in forms[0].controls:
    print control.name, control.type

And here is what I am getting (partially):

fb_dtsg hidden
friends_ids[] checkbox
None button
None hidden
None text
hometown_ids[] checkbox
None button
None hidden
None text
city_ids[] checkbox
None button
None hidden
None text
highschool_ids[] checkbox
None button
None hidden
None text
college_ids[] checkbox

So I am stucked here, as I can't apply the example from the tutorial (what I'd like to do is something like:

br['hometown'] = 'some town'

Does someone have a clue?

Thanks

S4M
  • 4,561
  • 6
  • 37
  • 47
  • 1
    I know that you can select forms by number by calling `form = br.select_form(nr=2)`, which selects the second form. Perhaps that would work with your controls as well? – inspectorG4dget Jul 24 '12 at 16:45
  • @inspectorG4dget Yes that's right! I dont know why I didnt think of it before. It's explained here: http://stackoverflow.com/questions/6359817/how-do-you-select-choices-in-a-form-using-python – S4M Jul 24 '12 at 17:06

1 Answers1

1

I originally posted this as a comment, but as it turns out to be the answer, I am re-posting it as an answer (Thanks @OP for the link to the question cited here).

According to this other SO question, you should be able to select the controls by index as well:

br = mechanize.Browser()
br.open('http://www.w3schools.com/html/html_forms.asp')
myControl = forms[N].controls[n]

In response to the comment "Actually thos is helpful as I get to access to the control I want, but it doesn't tell me how to modify it - ie an equivalent for br['control'] = 'my value'":

forms[N].controls[n] = myValue

Copying from here: Read this tutorial.

The basic idea is that you can get the control by index and set any legal value that you want to it directly

Community
  • 1
  • 1
inspectorG4dget
  • 110,290
  • 27
  • 149
  • 241
  • Actually thos is helpful as I get to access to the control I want, but it doesn't tell me how to modify it - ie an equivalent for br['control'] = 'my value' – S4M Jul 24 '12 at 19:01
  • after your edit: I am trying this line, but it has no effect. Indeed, I don't see how we could "map it back" to the browser object. – S4M Jul 24 '12 at 19:29
  • Ahh! you'd have to `form = br.select_form(nr = N)`, and then `form.controls[n] = myVal` and `form.submit()` (or is it `br.submit()`? I can never remember). That should handle the mapping back – inspectorG4dget Jul 24 '12 at 19:34
  • If I do form = br.select_form(nr = N), the form is of type 'NoneType', and thereforme doesn't have a 'controls' attribute. Really I am lost with this problem of mapping back the unnamed controls to my browser object :( – S4M Jul 24 '12 at 19:43
  • Are you sure that there are `N` forms on the page? I have a feeling you might be asking for the Nth form, when there are fewer forms on the page. – inspectorG4dget Jul 24 '12 at 19:44
  • Yes. As a test, I ran: form = br.select_form(nr=0) print dir(form) I don't get an attribute 'controls'. It's still a 'NoneType' for nr=0. – S4M Jul 24 '12 at 19:51
  • Try finding that form in HTML code and see what it looks like. Perhaps mechanize identifies things as forms that we don't consider to be forms (I'm really confused too - I'm just grabbing at straws here) – inspectorG4dget Jul 24 '12 at 20:11