2015-06-12 39 views
12

Tôi đang viết một hàm cho một số mã python hiện có sẽ được chuyển qua một đối tượng Trình duyệt cơ khí làm tham số.Khôi phục từ HTTPError trong Cơ chế

Tôi điền một số chi tiết vào biểu mẫu trong trình duyệt và sử dụng response = browser.submit() để chuyển trình duyệt sang trang mới và thu thập một số thông tin từ trình duyệt đó.

Thật không may, tôi thỉnh thoảng nhận được lỗi sau:

httperror_seek_wrapper: HTTP Error 500: Internal Server Error

 

tôi đã chuyển đến trang trong trình duyệt của riêng tôi, và chắc chắn đủ, tôi thỉnh thoảng gặp phải lỗi này trực tiếp, vì vậy tôi nghĩ rằng đây là một vấn đề máy chủ, không phải bất cứ điều gì để làm với robots.txt, tiêu đề hoặc tương tự.

Vấn đề là sau khi gửi, trạng thái của các thay đổi đối tượng browser và tôi không thể tiếp tục sử dụng nó. Suy nghĩ đầu tiên của tôi là cố gắng lấy một bản sao sâu đầu tiên và sử dụng nó nếu tôi gặp vấn đề, nhưng điều đó đưa ra lỗi TypeError: object.__new__(cStringIO.StringO) is not safe, use cStringIO.StringO.__new__() như được mô tả here.

Tôi cũng đã thử sử dụng browser.back() nhưng nhận được lỗi NoneType.

Có ai có giải pháp tốt cho điều này không?

 

Solution (với nhờ karnesJ.R dưới đây):

Một giải pháp tuyệt vời dưới đây sử dụng tuyệt vời requests thư viện (tài liệu here). requests có chức năng điền vào biểu mẫu và gửi qua post hoặc get, điều quan trọng là không thay đổi trạng thái của đối tượng br.

An excellent website cho phép chúng tôi kiểm tra nhiều mã lỗi khác nhau và có giao diện biểu mẫu ở trên cùng mà tôi đã thử nghiệm tính năng này. Tôi tạo đối tượng br tại trang web này, sau đó xác định hàm chọn biểu mẫu từ br, rút ​​ra thông tin có liên quan nhưng gửi thông qua requests - để đối tượng br không thay đổi và có thể sử dụng lại được. Mã lỗi gây ra requests để trả về rác, nhưng không hiển thị br không sử dụng được.

Như đã nêu bên dưới, điều này liên quan đến thời gian thiết lập ít hơn một chút, nhưng cũng đáng giá.

import mechanize 
import requests 

def testErrorCodes(br,theCodes): 
    for x in theCodes: 

     br.select_form(nr=0) 

     theAction = br.action 
     payload = {'code': x} 

     response = requests.post(theAction, data=payload) 
     print response.status_code 

br=mechanize.Browser() 
br.set_handle_robots(False) 
response = br.open("http://savanttools.com/test-http-status-codes") 

testErrorCodes(br,[401,402,403,404,500,503,504]) # Prints the error codes 

testErrorCodes(br,[404]) # The browser is still alive and well to be used again! 
+2

Bạn có thể cập nhật cho chúng tôi mã mà bạn đã sử dụng cho đến bây giờ không? –

+0

Bạn có thể thử sử dụng selenuim. – ssundarraj

+0

Bạn có thể hiển thị mã của mình hoặc cung cấp URL trang web bạn đang cố truy cập không? – 0605002

Trả lời

4

Đã một thời gian kể từ khi tôi viết cho python, nhưng tôi nghĩ rằng tôi có một giải pháp cho vấn đề của bạn.Hãy thử phương thức này:

import requests 
except Mechanize.HTTPError: 
    while true: ## DANGER ## 
     ## You will need to format and/or decode the POST for your form 
     response = requests.post('http://yourwebsite.com/formlink', data=None, json=None) 
     ## If the server will accept JSON formatting, this becomes trivial 
     if response.status_code == accepted_code: break 

Bạn có thể tìm tài liệu về thư viện requestshere. Cá nhân tôi nghĩ rằng requests là tốt hơn cho trường hợp của bạn hơn mechanize ... nhưng nó đòi hỏi một chi phí cao hơn một chút từ bạn trong đó bạn cần phải phá vỡ các đệ trình POST thô bằng cách sử dụng một số loại máy đánh chặn RESTful trong trình duyệt của bạn.

Cuối cùng, bằng cách đi qua trong br bạn đang hạn chế bản thân theo cách cơ giới hóa xử lý trạng thái trình duyệt trên br.submit().

+0

Tác phẩm này - Tôi đã chỉnh sửa câu hỏi của mình ở trên để kết hợp thông tin chi tiết của bạn. 'requests' chắc chắn là giao diện đẹp hơn' mechanize'. Bounty cũng kiếm được! – StackG

1

Tôi giả định rằng bạn muốn việc gửi xảy ra ngay cả khi có nhiều lần thử.

Giải pháp mà tôi nghĩ là chắc chắn không hiệu quả, nhưng nó sẽ hoạt động.

def do_something_in_mechanize(): 
    <...insert your code here...> 
    try: 
     browser.submit() 
     <...rest of your code...> 
    except mechanize.HTTPError: 
     do_something_in_mechanize() 

Về cơ bản, nó sẽ gọi hàm cho đến khi hành động được thực hiện mà không cần HTTPError s.

+0

Vấn đề là trình duyệt được chuyển thành tham số - tôi cần phải lặp lại bước 'browser.submit()' trong khối 'except', nhưng theo giai đoạn đó trình duyệt đã thay đổi trạng thái và gọi lại 'browser.submit()' gây ra lỗi 'NoneType' - nếu bạn đặt' browser' vào 'do_something_in_mechanize()', nó sẽ không hoạt động sau khi một hàm 'HTTPError' – StackG

+0

làm do_something_in_mechanize() nên chứa toàn bộ mã từ việc khởi tạo trình duyệt đến cuối. Nếu điều đó là khả thi, giải pháp này sẽ hoạt động. – ssundarraj

+0

Thật không may, đây chính xác là vấn đề - 'trình duyệt' đang được chuyển tới mã của tôi như một tham số, mà tôi không kiểm soát được. – StackG

Các vấn đề liên quan