我正在尝试使用机械化(v0.2.5)处理页面上的表单,该页面具有禁用的图像作为表单元素之一。当我尝试选择表单时,mechanize会引发一个AttributeError: control 'test' is disabled,其中test是禁用控件的名称。例如,

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

导致此堆栈跟踪:
    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

检查机械化源代码,当存在任何形式为mechanize.SubmitControl且没有预定义value属性的表单元素时,似乎总是会出现此错误。例如,以下形式将引发相同的错误:
<form action="http://whatever" method="POST">
    <input name="test" type="submit" disabled="disabled" />
</form>

我不确定这是否应视为错误,但是无论如何,是否有解决方法?例如,有没有办法我可以在调用br.select_form()之前更改目标页面的HTML以启用禁用的控件?

编辑

我已提交了一个补丁来机械化该问题。

最佳答案

不幸的是,已经一年多了,上游的机械化已经有了still not merged the pull request

同时,您可以使用我编写的此猴子补丁来解决该错误,而无需手动安装补丁程序版本。希望此错误将在(如果)0.2.6发布时得到解决,因此该修补程序仅适用于0.2.5和更早版本。

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__

10-07 14:54