2015-10-18 56 views
1

我已經做了一個使用api請求某些數據的python代碼,但api只允許每分鐘發送20個請求。我正在使用urllib來請求數據。另外我使用一個for循環,因爲數據位於一個文件:Python:每分鐘只需要請求20次

for i in hashfile: 
    hash = i 
    url1 = "https://hashes.org/api.php?act=REQUEST&key="+key+"&hash="+hash 
    print(url1) 
    response = urllib.request.urlopen(url2).read() 
    strr = str(response) 

    if "plain" in strr: 
     parsed_json = json.loads(response.decode("UTF-8")) 
     print(parsed_json['739c5b1cd5681e668f689aa66bcc254c']['plain']) 
     writehash = i+parsed_json 
     hashfile.write(writehash + "\n") 
    elif "INVALID HASH" in strr: 
     print("You have entered an invalid hash.") 
    elif "NOT FOUND" in strr: 
     print("The hash is not found.") 
    elif "LIMIT REACHED" in strr: 
     print("You have reached the max requests per minute, please try again in one minute.") 
    elif "INVALID KEY!" in strr: 
     print("You have entered a wrong key!") 
    else: 
     print("You have entered a wrong input!") 

有沒有辦法讓它只是做每分鐘20個請求?或者如果這是不可能的,我可以讓它在20次嘗試後超時? (順便說一句,它只是代碼的一部分)

回答

2

你想使用time模塊。每個循環結束時添加一個time.sleep(3),您將每分鐘最多收到20個請求。

4

time.sleep(3)保證不會對你每分鐘超過20個請求你的代碼,但它可能會不必要地耽誤允許請求:想象一下,你需要做只有10個請求:time.sleep(3)每個請求使循環運行半分鐘後但是api允許你在這種情況下一次完成所有10個請求(或者至少一個接一個)。

要強制每分鐘20所請求的限制而不會延遲初始請求,你可以使用RatedSemaphore(20, period=60)

rate_limit = RatedSemaphore(20, 60) 
for hash_value in hash_file: 
    with rate_limit, urlopen(make_url(hash_value)) as response: 
     data = json.load(response) 

你甚至可以一次進行多次請求,同時遵守限速:

from multiprocessing.pool import ThreadPool 

def make_request(hash_value, rate_limit=RatedSemaphore(20, 60)): 
    with rate_limit: 
     try: 
      with urlopen(make_url(hash_value)) as response: 
       return json.load(response), None 
     except Exception as e: 
       return None, e 


pool = ThreadPool(4) # make 4 concurrent requests 
for data, error in pool.imap_unordered(make_request, hash_file): 
    if error is None: 
     print(data)