我正在尝试修改此处显示的解决方案:What is the fastest way to send 100,000 HTTP requests in Python?,除了检查标头状态而不是我正在发出返回字典的API请求,我希望所有这些API请求的最终结果都是所有词典的列表。
这是我的代码 - 考虑到api_calls是一个列表,其中包含为json请求打开的每个URL ...
from threading import Thread
from Queue import Queue
concurrent = 200
def doWork():
while True:
url = q.get()
result = makeRequest(url[0])
doSomethingWithResult(result, url)
q.task_done()
def makeRequest(ourl):
try:
api_call = urlopen(ourl).read()
result = json.loads(api_call)
return result, ourl
except:
return "error", ourl
def doSomethingWithResult(result, url):
print(url,result)
q = Queue(concurrent * 2)
for i in range(concurrent):
t = Thread(target=doWork)
t.daemon = True
t.start()
try:
for url in api_calls:
q.put(url)
q.join()
except KeyboardInterrupt:
sys.exit(1)
与链接的示例一样,目前这将成功打印每行上的url结果。我想要做的是将(url,result)添加到每个线程的列表中,然后在最后将它们连接到一个主列表中。我无法弄清楚如何拥有这个主列表并在最后加入结果。任何人都可以帮助我在doSomethingWithResult中修改的内容吗?如果我正在做一个大循环,我只会有一个空列表,我会在每个API请求后将结果附加到列表中,但我现在不知道如何模仿这个我正在使用线程。
我希望一个共同的回答是使用https://en.wikipedia.org/wiki/Asynchronous_I/O,如果这是建议,那么我会感谢有人提供了一个例子来完成我上面链接的代码。
答案 0 :(得分:4)
请改用ThreadPool
。它为你做了繁重的工作。这是一个提取几个网址的工作示例。
import multiprocessing.pool
concurrent = 200
def makeRequest(ourl):
try:
api_call = urlopen(ourl).read()
result = json.loads(api_call)
return "success", ourl
except:
return "error", ourl
def main():
api_calls = [
'http:http://jsonplaceholder.typicode.com/posts/{}'.format(i)
for i in range(1,5)]
# a thread pool that implements the process pool API.
pool = multiprocessing.pool.ThreadPool(processes=concurrent)
return_list = pool.map(makeRequest, api_calls, chunksize=1)
pool.close()
for status, data in return_list:
print(data)
main()