【问题标题】:How to use tornado's asynchttpclient alone?如何单独使用tornado的asynchttpclient?
【发布时间】:2015-08-17 10:51:01
【问题描述】:

我是龙卷风的新手。

我想要的是编写一些函数来异步获取网页。由于这里不涉及请求处理程序、应用程序或服务器,我想我可以单独使用 tornado.httpclient.AsyncHTTPClient。 但是所有示例代码似乎都在龙卷风服务器或请求处理程序中。当我尝试单独使用它时,它永远不会起作用。 例如:

def handle(self,response):
    print response
    print response.body


@tornado.web.asynchronous
def fetch(self,url):
    client=tornado.httpclient.AsyncHTTPClient()
    client.fetch(url,self.handle)

fetch('http://www.baidu.com')

它说“'str'对象没有属性'application'”,但我想单独使用它?

或:

@tornado.gen.coroutine
def fetch_with_coroutine(url):
    client=tornado.httpclient.AsyncHTTPClient()
    response=yield http_client.fetch(url)
    print response
    print response.body
    raise gen.Return(response.body)
fetch_with_coroutine('http://www.baidu.com')

也不行。

之前,我尝试将回调传递给 AsyncHTTPHandler.fetch,然后启动 IOLoop,它可以工作并打印网页源代码。但我不知道如何处理 ioloop。

【问题讨论】:

    标签: python asynchronous tornado


    【解决方案1】:

    @tornado.web.asynchronous只能应用于RequestHandler子类中的某些方法;它不适合这种用法。

    您的第二个示例是正确的结构,但您需要实际运行 IOLoop。在批处理式程序中执行此操作的最佳方法是IOLoop.current().run_sync(fetch_with_coroutine)。这将启动 IOLoop,运行您的回调,然后停止 IOLoop。您应该在run_sync() 中运行一个函数,然后在该函数中使用yield 来调用任何其他协程。

    更完整的例子见https://github.com/tornadoweb/tornado/blob/master/demos/webspider/webspider.py

    【讨论】:

    • 我在发这篇文章时注意到了 run_sync。你的意思是如果我每次发出请求时启动和停止ioloop就没有问题,并且它仍然异步运行?
    • 使用 Tornado 的正常方式是只调用一次 run_sync()(或 start())。多次调用run_sync()(测试中除外)是不寻常的,并且在大多数情况下,它会忽略异步编程的要点(通过将异步操作变为同步,您会消除并发优势)。
    【解决方案2】:

    这是我过去用过的一个例子……

    from tornado.httpclient import AsyncHTTPClient
    from tornado.ioloop import IOLoop
    
    AsyncHTTPClient.configure(None, defaults=dict(user_agent="MyUserAgent"))
    http_client = AsyncHTTPClient()
    
    
    def handle_response(response):
        if response.error:
            print("Error: %s" % response.error)
        else:
            print(response.body)
    
    
    async def get_content():
        await http_client.fetch("https://www.integralist.co.uk/", handle_response)
    
    
    async def main():
        await get_content()
        print("I won't wait for get_content to finish. I'll show immediately.")
    
    if __name__ == "__main__":
        io_loop = IOLoop.current()
        io_loop.run_sync(main)
    

    我还详细介绍了如何将 Pipenv 与 tox.ini 和 Flake8 与这个龙卷风示例一起使用,这样其他人应该能够更快地启动和运行https://gist.github.com/fd603239cacbb3d3d317950905b76096

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多