Posting a file with mechanize and Python

I’ve been using the Python version of Mechanize to write some unit tests. I needed to post a file (an image) to a site I’d previously not fetched a form from, so I had to construct a form “on the fly”, which isn’t well documented.

After futzing around a bit, I figured it out:

browser.form = \
HTMLForm('http://absolute.path.to.submit.form',
method='POST', enctype='multipart/form-data')
browser.form.new_control('file', form_field_name, {'id':form_field_id})
browser.form.new_control('submit', 'Button', {})
browser.form.add_file(open(image_filename), 'image/jpeg', image_filename,
id=form_field_id)
browser.form.set_all_readonly(False)
browser.form.fixup()

# Submit it!
response = browser.submit()
html = response.read()

Critical bits:

  • http://absolute.path.to.submit.form’ must be the absolute path to submit the form to. It can’t be a relative path since you presumably haven’t fetched a form before, and mechanize can’t tell what it’s relative to.
  • enctype=’multipart/form-data’ VERY important. If you omit this, then the browser.submit() will skip submitting the file data, making the whole exercise worthless.
  • ‘form_field_name’ is the HTML form field name your application is expecting the file data to arrive as.
  • ‘form_field_id’ identifies which HTML control (in this case, the “control” is the “File” control) add_file is to add the file data too. You could have also used “name=form_field_name” to correlate the add_file to the new_control

That’s it!

,

  1. #1 by W on 2011.10.19 - 1:10 am

    thanks for this one 🙂 very helpful. enjoy your day

  2. #2 by 27 on 2011.04.16 - 5:01 pm

    The answer is yes i would pay for it in a hart beet

  3. #3 by Gollum on 2011.03.27 - 8:48 am

Leave a comment