Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mechanize cannot read form with SubmitControl that is disabled and has no value

I'm attempting to use mechanize (v0.2.5) to work with a form on a page that has a disabled image as one of the form elements. When I try to select the form, mechanize raises an AttributeError: control 'test' is disabled where test is the name of the disabled control. For example,

br = mechanize.Browser(factory=mechanize.RobustFactory())
br.open("http://whatever...")
br.select_form(nr=0)

Leads to this stack trace:

    br.select_form(nr=0)
  File "build\bdist.win32\egg\mechanize\_mechanize.py", line 499, in select_form
  File "build\bdist.win32\egg\mechanize\_html.py", line 544, in __getattr__
  File "build\bdist.win32\egg\mechanize\_html.py", line 557, in forms
  File "build\bdist.win32\egg\mechanize\_html.py", line 237, in forms
  File "build\bdist.win32\egg\mechanize\_form.py", line 844, in ParseResponseEx
  File "build\bdist.win32\egg\mechanize\_form.py", line 1017, in _ParseFileEx
  File "build\bdist.win32\egg\mechanize\_form.py", line 2735, in new_control
  File "build\bdist.win32\egg\mechanize\_form.py", line 2336, in __init__
  File "build\bdist.win32\egg\mechanize\_form.py", line 1221, in __setattr__
AttributeError: control 'test' is disabled

Examining the mechanize source code, it looks as if this error will always be raised when there is any form element that evaluates to a mechanize.SubmitControl and that has no pre-defined value attribute. For example, the following form would raise the same error:

<form action="http://whatever" method="POST">
    <input name="test" type="submit" disabled="disabled" />
</form>

I'm not sure if this should count as a bug, but in any case is there a workaround? For instance, is there a way I can alter the HTML of the target page to enable the disabled controls before I call br.select_form()?

EDIT

I've submitted a patch to mechanize that fixes this problem.

like image 265
Abiel Avatar asked Feb 12 '12 15:02

Abiel


1 Answers

Sadly it's been more than a year and the mechanize upstream has still not merged the pull request.

Meanwhile you can use this monkey-patch I wrote to work around the bug without needing to manually install a patched version. Hopefully this bug will be resolved when (if) 0.2.6 is released, so the patch only applies to versions 0.2.5 and earlier.

def monkeypatch_mechanize():
    """Work-around for a mechanize 0.2.5 bug. See: https://github.com/jjlee/mechanize/pull/58"""
    import mechanize
    if mechanize.__version__ < (0, 2, 6):
        from mechanize._form import SubmitControl, ScalarControl

        def __init__(self, type, name, attrs, index=None):
            ScalarControl.__init__(self, type, name, attrs, index)
            # IE5 defaults SUBMIT value to "Submit Query"; Firebird 0.6 leaves it
            # blank, Konqueror 3.1 defaults to "Submit".  HTML spec. doesn't seem
            # to define this.
            if self.value is None:
                if self.disabled:
                    self.disabled = False
                    self.value = ""
                    self.disabled = True
                else:
                    self.value = ""
            self.readonly = True

        SubmitControl.__init__ = __init__
like image 106
intgr Avatar answered Nov 16 '22 00:11

intgr