2009-09-02 56 views
7

我想读取一个网站异步,这是不可能的,据我所知urllib。现在我试着用简单的套接字来阅读,但是HTTP给了我一个地狱。 我遇到了各种各样的时髦编码,例如传输编码:分块,必须手动解析所有的东西,我觉得现在编码C,而不是Python。用asyncore读取一个网站

是不是有一个更好的方式,像URLLib,异步?我真的不想重新实现整个HTTP规范,当它完成之前就完成了。

当前扭曲的选项。

问候,

汤姆

回答

5

你看着http://asynchttp.sourceforge.net/?为Python

的“asynchttp”模块是Python库‘asynchat’模块,它是建立在‘asyncore’和‘选择’模块的逻辑延伸。我们的目标是

“异步HTTP客户端在不使用阻塞套接字的情况下提供出色的'httplib'模块的功能。“

该项目的最后一次提交是2001-05-29,因此它看起来死了。但无论如何它可能是有趣的。

声明:我自己没有用过。

另外,this blog post有一些关于异步HTTP的信息。

7

可以实现异步调用自己。对于每个调用,启动一个新线程(或尝试从一个池中获取一个线程)并使用回调来处理它。

你可以用一个装饰做到这一点非常漂亮:

def threaded(callback=lambda *args, **kwargs: None, daemonic=False): 
    """Decorate a function to run in its own thread and report the result 
    by calling callback with it.""" 
    def innerDecorator(func): 
     def inner(*args, **kwargs): 
      target = lambda: callback(func(*args, **kwargs)) 
      t = threading.Thread(target=target) 
      t.setDaemon(daemonic) 
      t.start() 
     return inner 
    return innerDecorator 

@threaded() 
def get_webpage(url): 
    data = urllib.urlopen(url).read() 
    print data 
+2

对不起,我说,我要异步插座,而不是线程。 – Tom 2009-09-02 13:09:33

+1

我是唯一认为这个解决方案*辉煌*的人吗?比所有其他异步HTTP方法更好的是它实际上是一个完全通用的异步解决方案,用于* anything *。你可以用你想要的任何代码替换'get_webpage',并让它异步发生。 – robru 2012-08-31 23:43:25

1

我来的最远的地方是使用修改后的asynchttp,codeape建议。我曾尝试使用asyncore/asynchat和asynchttp,并带来很多痛苦。我花了太多的时间来尝试修复所有的错误(有一个方法handle_read,几乎从asyncore复制,只是严重缩进,并给我头痛的分块编码)。此外,asyncore和asynchat最好不要根据我在谷歌上提供的一些提示来使用。

我已经解决了扭曲,但这显然不适合你。

它也可能取决于什么是你想与你的应用程序,你为什么要异步请求,如果线程是一种选择或没有,如果你正在做的GUI编程或别的东西,所以如果你能提供一些线索更inforation ,这总是很好。如果没有,我会投票支持上面提到的线程版本,它提供了更多的可读性和可维护性。

1

Asyncore简单的HTTP客户端的例子是非常简单:)

http://docs.python.org/library/asyncore.html

import asyncore, socket 

class HTTPClient(asyncore.dispatcher): 

    def __init__(self, host, path): 
     asyncore.dispatcher.__init__(self) 
     self.create_socket(socket.AF_INET, socket.SOCK_STREAM) 
     self.connect((host, 80)) 
     self.buffer = 'GET %s HTTP/1.0\r\n\r\n' % path 

    def handle_connect(self): 
     pass 

    def handle_close(self): 
     self.close() 

    def handle_read(self): 
     print self.recv(8192) 

    def writable(self): 
     return (len(self.buffer) > 0) 

    def handle_write(self): 
     sent = self.send(self.buffer) 
     self.buffer = self.buffer[sent:] 


client = HTTPClient('www.python.org', '/') 
asyncore.loop()