2012-02-12 26 views
8

Tôi đang cố sử dụng cơ giới hóa (v0.2.5) để làm việc với biểu mẫu trên trang có hình ảnh bị tắt là một trong các yếu tố biểu mẫu. Khi tôi cố gắng chọn biểu mẫu, cơ giới hóa sẽ đặt ra một số AttributeError: control 'test' is disabled trong đó test là tên của điều khiển bị vô hiệu hóa. Ví dụ,cơ giới hóa không thể đọc biểu mẫu với SubmitControl bị vô hiệu hóa và không có giá trị

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

Dẫn đến ngăn xếp này dấu vết:

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 

Kiểm tra mã nguồn cơ giới hóa, có vẻ như nếu lỗi này sẽ luôn được nâng lên khi có bất kỳ yếu tố hình thức mà đánh giá một mechanize.SubmitControl và điều đó không có thuộc tính được xác định trước value. Ví dụ: biểu mẫu sau sẽ tăng cùng một lỗi:

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

Tôi không chắc liệu điều này có được tính là lỗi hay không, nhưng trong mọi trường hợp có cách giải quyết khác không? Ví dụ: có cách nào tôi có thể thay đổi HTML của trang đích để bật các điều khiển bị tắt trước khi tôi gọi br.select_form() không?

EDIT

tôi đã gửi một bản vá để cơ giới hóa điều này khắc phục vấn đề này.

+2

Cảm ơn bạn! Đây là một cuộc sống tiết kiệm. Đối với bất kỳ ai gặp sự cố khi vá lỗi này - Repo có tại đây: [https://github.com/abielr/mechanize](https://github.com/abielr/mechanize), tải xuống mã nguồn và sau đó sử dụng thiết lập '$ python. py install' Tôi hy vọng họ mang lại sửa chữa của bạn trong phiên bản tiếp theo :-) – aknatn

Trả lời

0

Đây chắc chắn là lỗi, báo cáo ngược dòng, tạo bản vá, gửi lên luồng và sử dụng phiên bản được vá trong thời gian chờ đợi là cách khá phù hợp để xử lý. (Cảm ơn bạn đã chọn cách đó.)

Như bạn đã đề cập, một cách tiếp cận khác đang làm việc xung quanh bằng HTML nguồn tiền xử lý (có thể hữu ích nếu bạn vội vàng hoặc không thể/không muốn sử dụng phiên bản được vá vì một số lý do, nhưng lưu ý rằng cách giải quyết không giúp ích cho cộng đồng). Đối với xử lý hậu kỳ, bất kỳ phương thức phù hợp nào cũng có thể được sử dụng - từ str.replace() đến xử lý cấp DOM với BeautifulSoup hoặc lxml.

8

Đáng buồn là đã hơn một năm và cơ chế ngược dòng có still not merged the pull request.

Trong khi đó, bạn có thể sử dụng miếng vá khỉ mà tôi đã viết để khắc phục lỗi mà không cần phải cài đặt phiên bản được vá theo cách thủ công. Hy vọng rằng lỗi này sẽ được giải quyết khi (nếu) 0.2.6 được phát hành, vì vậy bản vá chỉ áp dụng cho các phiên bản 0.2.5 và trước đó.

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__ 
Các vấn đề liên quan