我想读取一个网站异步,这是不可能的,据我所知urllib。现在我试着用简单的套接字来阅读,但是HTTP给了我一个地狱。 我遇到了各种各样的时髦编码,例如传输编码:分块,必须手动解析所有的东西,我觉得现在编码C,而不是Python。用asyncore读取一个网站
是不是有一个更好的方式,像URLLib,异步?我真的不想重新实现整个HTTP规范,当它完成之前就完成了。
当前扭曲的选项。
问候,
汤姆
我想读取一个网站异步,这是不可能的,据我所知urllib。现在我试着用简单的套接字来阅读,但是HTTP给了我一个地狱。 我遇到了各种各样的时髦编码,例如传输编码:分块,必须手动解析所有的东西,我觉得现在编码C,而不是Python。用asyncore读取一个网站
是不是有一个更好的方式,像URLLib,异步?我真的不想重新实现整个HTTP规范,当它完成之前就完成了。
当前扭曲的选项。
问候,
汤姆
你看着http://asynchttp.sourceforge.net/?为Python
的“asynchttp”模块是Python库‘asynchat’模块,它是建立在‘asyncore’和‘选择’模块的逻辑延伸。我们的目标是
“异步HTTP客户端在不使用阻塞套接字的情况下提供出色的'httplib'模块的功能。“
该项目的最后一次提交是2001-05-29,因此它看起来死了。但无论如何它可能是有趣的。
声明:我自己没有用过。
另外,this blog post有一些关于异步HTTP的信息。
可以实现异步调用自己。对于每个调用,启动一个新线程(或尝试从一个池中获取一个线程)并使用回调来处理它。
你可以用一个装饰做到这一点非常漂亮:
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
我来的最远的地方是使用修改后的asynchttp,codeape建议。我曾尝试使用asyncore/asynchat和asynchttp,并带来很多痛苦。我花了太多的时间来尝试修复所有的错误(有一个方法handle_read,几乎从asyncore复制,只是严重缩进,并给我头痛的分块编码)。此外,asyncore和asynchat最好不要根据我在谷歌上提供的一些提示来使用。
我已经解决了扭曲,但这显然不适合你。
它也可能取决于什么是你想与你的应用程序,你为什么要异步请求,如果线程是一种选择或没有,如果你正在做的GUI编程或别的东西,所以如果你能提供一些线索更inforation ,这总是很好。如果没有,我会投票支持上面提到的线程版本,它提供了更多的可读性和可维护性。
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()
对不起,我说,我要异步插座,而不是线程。 – Tom 2009-09-02 13:09:33
我是唯一认为这个解决方案*辉煌*的人吗?比所有其他异步HTTP方法更好的是它实际上是一个完全通用的异步解决方案,用于* anything *。你可以用你想要的任何代码替换'get_webpage',并让它异步发生。 – robru 2012-08-31 23:43:25