如何在Python中创建异步HTTP GET请求并将响应对象传递给函数

时间:2013-07-31 17:56:36

标签: python http asynchronous python-requests

更新:Problem was incomplete documentation, event dispatcher passing kwargs to the hook function.

我有一个大约30k网址的列表,我想检查各种字符串。我有一个使用Requests&的脚本的工作版本。 BeautifulSoup,但它不使用线程或异步请求,所以它非常慢。

最终我想要做的是为每个URL缓存html,这样我就可以运行多次检查,而不会向每个站点发出冗余的HTTP请求。如果我有一个存储html的函数,那么异步发送HTTP GET请求然后传递响应对象的最佳方法是什么?

我一直在尝试使用Grequests(as described here)和“hooks”参数,但我收到错误和documentation doesn't go very in-depth。所以我希望有更多经验的人可以解释一下。

以下是我正在努力完成的一个简化示例:

import grequests

urls = ['http://www.google.com/finance','http://finance.yahoo.com/','http://www.bloomberg.com/']

def print_url(r):
    print r.url

def async(url_list):
    sites = []
    for u in url_list:
        rs = grequests.get(u, hooks=dict(response=print_url))
        sites.append(rs)
    return grequests.map(sites)

print async(urls)

它产生以下TypeError:

TypeError: print_url() got an unexpected keyword argument 'verify'
<Greenlet at 0x32803d8L: <bound method AsyncRequest.send of <grequests.AsyncRequest object at 0x00000000028D2160>>
(stream=False)> failed with TypeError

不确定为什么默认情况下它会将'verify'作为关键字参数发送;如果有人有任何建议(使用问候或其他方式)请分享:)

提前致谢。

1 个答案:

答案 0 :(得分:11)

我尝试了您的代码,可以通过在print_url函数中添加一个额外的参数 kwargs 来实现它。

def print_url(r, **kwargs):
    print r.url

我认为这个其他stackoverlow问题出了什么问题:Problems with hooks using Requests Python package

当您在grequests中使用响应挂钩时,您需要在回调定义中添加** kwargs。