尝试尝试并构建一个解决UrlRequest使用的类,以检查给定的URL是否有效。结果比预期的要困难一点!
问题是从未调用定义为类的一部分的on_success和on_failure / error方法。该脚本将抛出以下输出(基于打印命令):
http://www.google.com
request sent
URL doesn't work
现在我的怀疑是我从test_connection方法获得了返回码(“None”),而不是connectionSuccess或connectionFailure。如何让呼叫等待后者之一给出回报?欢迎任何建议。感谢。
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.network.urlrequest import UrlRequest
class WebExplorer():
def test_connection(self, path):
self.path = path
print (self.path)
req = UrlRequest(self.path,on_failure=self.connectionFailure,on_error=self.connectionFailure,on_success=self.connectionSuccess)
print ("request sent")
def connectionSuccess(self,*args):
print ("connectionSuccess")
return 0
def connectionFailure(self,*args):
print ("connectionFailure")
return 1
class MainScreen(FloatLayout):
def __init__(self, **kwargs):
super(MainScreen, self).__init__(**kwargs)
self.address = 'http://www.google.com'
if WebExplorer().test_connection(self.address) == 0:
print ("URL works")
else:
print ("URL doesn't work")
class App(App):
def build(self):
return MainScreen()
if __name__ == "__main__":
App().run()
更新2016-09-27 我改变了我的代码,我花了好几个小时试图弄清楚问题。首先是代码:
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.network.urlrequest import UrlRequest
class WebExplorer():
def test_connection(self, path):
self.path = path
req = UrlRequest(self.path,on_failure=self.connectionFailure,on_error=self.connectionFailure,on_success=self.connectionSuccess)
req.wait()
return (self._return_value)
def connectionSuccess(self, req, results):
print ("Success")
self._return_value = [0,results]
def connectionFailure(self, req, results):
print ("Failure")
self._return_value = [1,results]
class MainScreen(FloatLayout):
def __init__(self, **kwargs):
super(MainScreen, self).__init__(**kwargs)
self.URLtest = ['http://www.ikea.com/','https://www.google.com','https://www.sdfwrgaeh.com']
for URL in self.URLtest:
self.returnCode = WebExplorer().test_connection(URL)
if self.returnCode[0] == 0:
print ("Correct URL")
else:
print ("Wrong URL")
class App(App):
def build(self):
return MainScreen()
if __name__ == "__main__":
App().run()
为什么有3个网址?因为一个是“正确的”(宜家),一个是重定向(谷歌),一个是完全虚假的。事实证明,该代码仅适用于第一个。当结果是失败/错误时,req.wait不起作用(顺便说一句,我不知道这两者之间有什么区别)。
所以问题是如何使req.wait进程失败,或者如何使用正确的错误代码退出类。我认为Clock.schedule_interval定期检查状态,因为当URL不正确时甚至没有执行事件方法,我无处可设置我的变量-_-
答案 0 :(得分:0)
UrlRequest是一个异步,这意味着在您的应用程序进行时,后台会处理实际请求。函数on_failure
等是回调,即它们将在请求完成时被调用 - 但这意味着返回值是"丢失"。您获得的返回值确实来自test_connection
函数。
您在邮件列表中提到要对根网址进行调用,对您收到的内容进行一些处理,然后根据内容和用户互动向郊区发出新请求。
以下内容应为您尝试执行的操作提供框架。
class WebExplorer
def __init__(self, gui):
self._visited_urls = [] # to prevent endless redirect loops
self._visiting = set() # to check if we are still doing something
self.gui = gui # used to display buttons in process_result
def get_url(self, url):
self._visited_urls.append(url)
self._visiting.add(url)
UrlRequest(url,
on_success=self.process_result,
on_failure=self.failure,
on_error=self.failure, # what is the difference between failure and error?
on_redirect=self.redirect)
def redirect(self, req):
self._visiting.discard(req.url)
self.get_url(req.req_headers["Location"]) # check if correct handling of 3xx
def process_result(self, req):
self._visiting.discard(req.url)
#TODO process the body to extract urls you want to visit
box = BoxLayout()
for url in urls_you_want_to_visit:
button = Button()
button.text = url
# I'm not sure if the following works due to some scoping oddities
# if - no matter which button is pressed - the same url is called
# this line is probably at fault
button.bind(on_press=lambda: self.get_url(url))
box.add_widget(button)
gui.add_widget(box)
当然还有很多需要改进的地方。它也没有经过测试,因此它可能包含错误。