从机械化中的HTTPError中恢复

问题描述 投票:12回答:2

我正在为一些现有的python代码编写一个函数,该函数将通过Mechanize浏览器对象作为参数传递。

我在浏览器中的表单中填写了一些细节,并使用response = browser.submit()将浏览器移至新页面,并从中收集一些信息。

不幸的是,我偶尔会出现以下错误:

httperror_seek_wrapper: HTTP Error 500: Internal Server Error

我已经在自己的浏览器中导航到该页面,并且可以肯定的是,我偶尔会直接看到此错误,所以我认为这是服务器问题,与robots.txt,标题或类似内容无关。

问题是,提交后,browser对象的状态发生了变化,我无法继续使用它。我的第一个想法是尝试首先制作一个深层副本,如果遇到问题,请使用该副本,但这会产生错误TypeError: object.__new__(cStringIO.StringO) is not safe, use cStringIO.StringO.__new__(),如here所述。

我也尝试使用browser.back(),但出现NoneType错误。

有人对此有很好的解决方案吗?

解决方案(感谢下面的karnesJ.R):

以下一个很好的解决方案使用了出色的requests库(文档here)。 requests具有填写表格并通过postget提交的功能,重要的是不会更改br对象的状态。

excellent website允许我们测试各种错误代码,并且在顶部进行测试的是表单接口。我在此站点上创建了一个br对象,然后定义一个函数,该函数从br中选择表单,提取相关信息,但通过requests进行提交-这样br对象不变并且是可重复使用的。错误代码导致requests返回垃圾,但不要使br无法使用。

如下所述,这会花费更多的设置时间,但是非常值得。

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!
python mechanize http-error
2个回答
4
投票

自从我为python编写以来已经有一段时间了,但是我认为我有解决您问题的方法。试试这个方法:

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

您可以找到有关requestshere的文档。我个人认为requestsmechanize更适合您的情况...但是它确实需要您多一点开销,因为您需要使用浏览器中的某种RESTful拦截器将提交分解为原始POST 。

但是,最终,通过传入br,您将自己局限于机械化处理br.submit()上浏览器状态的方式。


1
投票

我假设即使要进行多次尝试,您也希望提交成功。

我想到的解决方案肯定不是有效的,但是应该可以。

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

基本上,它将调用该函数,直到没有HTTPError的情况下执行该动作为止。

© www.soinside.com 2019 - 2024. All rights reserved.