使用asyncore读取网站

7 投票
4 回答
2376 浏览
提问于 2025-04-15 14:01

我想要异步地读取一个网站,但我知道用urllib是做不到的。于是我尝试用普通的套接字来读取,但HTTP让我很头疼。

我遇到了各种奇怪的编码方式,比如说“transfer-encoding: chunked”,这些我都得手动解析,感觉现在在写C语言,而不是Python。

难道没有像URLLib那样更好的异步方法吗?我真的不想重新实现整个HTTP规范,因为这些东西之前都已经有人做过了。

目前Twisted也不是一个选项。

问候,

汤姆

4 个回答

1

我尝试过使用修改过的asynchttp,这是codeape推荐的。我试着用asyncore/asynchat和asynchttp,结果遇到了很多麻烦。花了我太多时间去修复里面的各种错误(有一个叫handle_read的方法,几乎是从asyncore复制过来的,只是缩进很糟糕,让我头疼不已,特别是在处理分块编码时)。而且,根据我在谷歌上找到的一些提示,asyncore和asynchat最好不要使用。

我最后选择了twisted,但这显然不适合你。

你想用你的应用程序做什么,以及为什么需要异步请求,这可能也会影响选择。如果线程是一个选项,或者你是在做图形界面编程,或者其他什么事情。如果你能提供更多信息,那就更好了。如果没有的话,我会推荐上面提到的线程版本,它在可读性和可维护性上都更好。

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
5

你有没有看过 http://asynchttp.sourceforge.net/?

“Python的异步HTTP客户端”

‘asynchttp’模块是Python库‘asynchat’模块的一个逻辑扩展,它是基于‘asyncore’和‘select’模块构建的。我们的目标是提供优秀的‘httplib’模块的功能,但不使用阻塞的套接字。

这个项目最后一次更新是在2001年5月29日,所以看起来已经停止维护了。不过它可能还是有一些参考价值。

免责声明:我自己没有使用过这个模块。

另外,这篇博客文章里有一些关于异步HTTP的信息。

撰写回答