从 Mechanize 中的 HTTPError 中恢复
Recovering from HTTPError in Mechanize
我正在为一些现有的 python 代码编写函数,这些代码将作为参数传递给 Mechanize 浏览器 object。
我在浏览器的表格中填写一些详细信息,然后使用response = browser.submit()
将浏览器移动到一个新页面,并从中收集一些信息。
不幸的是,我偶尔会遇到以下错误:
httperror_seek_wrapper: HTTP Error 500: Internal Server Error
我在自己的浏览器中导航到该页面,果然,我偶尔会直接看到这个错误,所以我认为这是服务器问题,与robots.txt
没有任何关系,headers 或类似的。
问题是提交后browser
object的状态变了,无法继续使用。我的第一个想法是先尝试进行深层复制,如果我 运行 遇到问题,请使用它,但这会产生错误 TypeError: object.__new__(cStringIO.StringO) is not safe, use cStringIO.StringO.__new__()
,如 here.
所述
我也尝试过使用 browser.back()
但出现 NoneType
错误。
有没有人对此有好的解决方案?
解决方案(感谢下方karnesJ.R):
下面的一个很好的解决方案使用了优秀的 requests
库(文档 here)。 requests
具有填写表格并通过 post
或 get
提交的功能,重要的是不会更改 br
object.[= 的状态32=]
excellent website 允许我们测试各种错误代码,并且在顶部有一个我测试过的表单界面。我在这个站点上创建了一个 br
object,然后定义了一个从 br
中选择表单的函数,提取了相关信息,但是通过 requests
提交了 - 所以br
object 没有改变并且是 re-usable。错误代码导致 requests
到 return 垃圾,但不会导致 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!
我假设您希望提交成功,即使需要多次尝试。
我想到的解决方案当然效率不高,但应该可以。
def do_something_in_mechanize():
<...insert your code here...>
try:
browser.submit()
<...rest of your code...>
except mechanize.HTTPError:
do_something_in_mechanize()
基本上,它会调用该函数,直到在没有 HTTPError
的情况下执行操作。
自从我为 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
您可以找到有关 requests
库 here 的文档。我个人认为 requests
比 mechanize
更适合你的情况......但它确实需要你多一点开销,因为你需要分解提交到原始 POST 使用浏览器中的某种 RESTful 拦截器。
但最终,通过传入 br
,您将自己限制在 br.submit()
.
上 mechanize 处理浏览器状态的方式
我正在为一些现有的 python 代码编写函数,这些代码将作为参数传递给 Mechanize 浏览器 object。
我在浏览器的表格中填写一些详细信息,然后使用response = browser.submit()
将浏览器移动到一个新页面,并从中收集一些信息。
不幸的是,我偶尔会遇到以下错误:
httperror_seek_wrapper: HTTP Error 500: Internal Server Error
我在自己的浏览器中导航到该页面,果然,我偶尔会直接看到这个错误,所以我认为这是服务器问题,与robots.txt
没有任何关系,headers 或类似的。
问题是提交后browser
object的状态变了,无法继续使用。我的第一个想法是先尝试进行深层复制,如果我 运行 遇到问题,请使用它,但这会产生错误 TypeError: object.__new__(cStringIO.StringO) is not safe, use cStringIO.StringO.__new__()
,如 here.
我也尝试过使用 browser.back()
但出现 NoneType
错误。
有没有人对此有好的解决方案?
解决方案(感谢下方karnesJ.R):
下面的一个很好的解决方案使用了优秀的 requests
库(文档 here)。 requests
具有填写表格并通过 post
或 get
提交的功能,重要的是不会更改 br
object.[= 的状态32=]
excellent website 允许我们测试各种错误代码,并且在顶部有一个我测试过的表单界面。我在这个站点上创建了一个 br
object,然后定义了一个从 br
中选择表单的函数,提取了相关信息,但是通过 requests
提交了 - 所以br
object 没有改变并且是 re-usable。错误代码导致 requests
到 return 垃圾,但不会导致 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!
我假设您希望提交成功,即使需要多次尝试。
我想到的解决方案当然效率不高,但应该可以。
def do_something_in_mechanize():
<...insert your code here...>
try:
browser.submit()
<...rest of your code...>
except mechanize.HTTPError:
do_something_in_mechanize()
基本上,它会调用该函数,直到在没有 HTTPError
的情况下执行操作。
自从我为 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
您可以找到有关 requests
库 here 的文档。我个人认为 requests
比 mechanize
更适合你的情况......但它确实需要你多一点开销,因为你需要分解提交到原始 POST 使用浏览器中的某种 RESTful 拦截器。
但最终,通过传入 br
,您将自己限制在 br.submit()
.