You can use blockonomics, its pretty fast. It also has API to give balance of given xpub.
If you don't want to submit your xpub to server you can use https://github.com/dan-da/hd-wallet-addrs. This will select random balance API service for each address and do HD walkthrough.
Added example code using blockr api, fetches balances for 20 addreses at once, should be pretty fast
import pycoin.key
import sys
import os
os.environ["PYCOIN_NATIVE"]="openssl"
import requests
BATCH_SIZE = 20
BLOCKR_URL= "http://btc.blockr.io/api/v1/address/info"
def get_used_addresses(xpub, account_type):
xpub_subkey = xpub.subkey(account_type)
index = 0
addr_batch = []
output = []
while True:
addr = xpub_subkey.subkey(index).bitcoin_address()
addr_batch.append(addr)
if (index+1)%BATCH_SIZE==0:
results = requests.get("{}/{}".format(BLOCKR_URL, ",".join(addr_batch))).json()
addr_batch = []
used_addrs = [x["address"] for x in results['data'] if not x["is_unknown"]]
if (used_addrs):
output.extend(used_addrs)
else:
break
index += 1
return output
def main():
xpub = pycoin.key.Key.from_text(sys.argv[1])
result = []
result.extend(get_used_addresses(xpub, 0))
result.extend(get_used_addresses(xpub, 1))
print result
if __name__ == "__main__":
main()