2012-02-12 22 views
8

Estoy intentando usar mechanize (v0.2.5) para trabajar con un formulario en una página que tiene una imagen desactivada como uno de los elementos del formulario. Cuando trato de seleccionar el formulario, mechanize plantea un AttributeError: control 'test' is disabled donde test es el nombre del control deshabilitado. Por ejemplo,mecanizar no puede leer el formulario con SubmitControl que está deshabilitado y no tiene ningún valor

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

conduce a esta Seguimiento de la pila:

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 

Evaluación del código fuente mecanizar, parece como si siempre se elevará este error cuando no hay ningún elemento de la forma que se evalúa como un mechanize.SubmitControl y que no tiene un atributo predefinido value. Por ejemplo, la siguiente forma aumentaría el mismo error:

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

No estoy seguro de si esto debería contar como un insecto, pero en cualquier caso es que hay alguna solución? Por ejemplo, ¿hay alguna manera de modificar el código HTML de la página de destino para habilitar los controles deshabilitados antes de llamar al br.select_form()?

EDITAR

He presentado un parche para mecanizar que soluciona este problema.

+2

¡Gracias! Esto fue un salvavidas. Para cualquier persona que tenga problemas parcheando esto, Repo está aquí: [https://github.com/abielr/mechanize](https://github.com/abielr/mechanize), descargue el código fuente de origen y luego use '$ python setup. py install' Espero que traigan su solución en la próxima versión :-) – aknatn

Respuesta

0

Esto es definitivamente un error, informarlo en sentido ascendente, hacer un parche, enviarlo en sentido ascendente y usar una versión parcheada mientras tanto es una manera bastante correcta de manejarlo. (Gracias por elegir de esa manera.)

Como mencionaste, otro enfoque es solucionarlo preprocesando HTML fuente (que puede ser útil si tienes prisa, o no puedes/no quieres) use la versión parchada por alguna razón, pero tenga en cuenta que las soluciones no ayudan a la comunidad). Para el post-procesamiento, se puede usar cualquier método adecuado, desde str.replace() hasta el procesamiento DOM-level con BeautifulSoup o lxml.

8

Lamentablemente ha pasado más de un año y el mecanizado aguas arriba tiene still not merged the pull request.

Mientras tanto puedes usar este parche de mono que escribí para evitar el error sin la necesidad de instalar manualmente una versión parchada. Con suerte, este error se resolverá cuando se libere (if) 0.2.6, por lo que el parche solo se aplica a las versiones 0.2.5 y anteriores.

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__ 
Cuestiones relacionadas