This text file consists of three Python files. The first is a very slightly adapted code fount on github, which listens for new blocks from the blockchain.info websocket API. Change the file output location to whatever you prefer, and let it run as long as you want to collect as many blocks as you need. The next two files must be run in sequence (you can leave the first running if you wish). File 2 takes the output of the listener routine and turns it into CSV timestamps. File 3 takes that and turns it into a CSV of time-between-blocks. This output can then be analyzed in whatever way you wish. # FILE 1: bitcoin_listener # -*- coding: utf-8 -*- # by fcicq , 2013.4.7, GPLv2 # Tornado 3.0 is required. """ Original code at: https://gist.github.com/fcicq/5328876/ Extremely minor modifications by Matt Springer """ from tornado.websocket import websocket_connect, WebSocketClientConnection from tornado.ioloop import IOLoop from datetime import timedelta import time #echo_uri = 'ws://echo.websocket.org' echo_uri = 'ws://ws.blockchain.info/inv' PING_TIMEOUT = 15 class myws(): conn = None keepalive = None def __init__(self, uri): self.uri = uri self.doconn() def doconn(self): w = websocket_connect(self.uri) w.add_done_callback(self.wsconnection_cb) def dokeepalive(self): stream = self.conn.protocol.stream if not stream.closed(): self.keepalive = stream.io_loop.add_timeout(timedelta(seconds=PING_TIMEOUT), self.dokeepalive) self.conn.protocol.write_ping("") else: self.keepalive = None # should never happen def wsconnection_cb(self, conn): self.conn = conn.result() self.conn.on_message = self.message self.conn.write_message('{"op":"ping_block"}') self.conn.write_message('{"op":"blocks_sub"}') # self.conn.write_message('{"op":"unconfirmed_sub"}') self.keepalive = IOLoop.instance().add_timeout(timedelta(seconds=PING_TIMEOUT), self.dokeepalive) def message(self, message): if message is not None: output = str(message) + str(time.time()) print(output) with open('c:\users\matt\desktop\log.txt', 'a') as the_file: the_file.write(output) the_file.write('\n') the_file.close() else: self.close() def close(self): print('conn closed') if self.keepalive is not None: keepalive = self.keepalive self.keepalive = None IOLoop.instance().remove_timeout(keepalive) self.doconn() import signal def main(): try: io_loop = IOLoop.instance() signal.signal(signal.SIGTERM, io_loop.stop) myws(echo_uri) IOLoop.instance().start() except KeyboardInterrupt: io_loop.stop() if __name__ == '__main__': main() # FILE 2: bitcoin_parser # -*- coding: utf-8 -*- """ Coded by Matt Springer This work is licensed under a Creative Commons Attribution 4.0 International License. """ from __future__ import print_function import re def getHeight(string): '''Regex which matches the 6 digits following "height" in the received block''' regex = re.compile("(?<=\"height\":)[0-9]{6}") result = regex.findall(string) return int(result[0]) def getReportedTime(string): '''Extacts the number after the first "time" in the received block''' regex = re.compile("(?<=\"time\":)[0-9]{10}") result = regex.findall(string) return int(result[0]) def getBlockchainTime(string): '''Extacts the number after the second "time" in the received block ''' regex = re.compile("(?<=\"time\":)[0-9]{10}") result = regex.findall(string) return int(result[1]) def getMyTime(string): '''Extacts the number after the three}}}, which is the local machine timestamp I appended in bitcoin_listener''' regex = re.compile("(?<=\}\}\})[0-9]{10}") result = regex.findall(string) return int(result[0]) def main(): '''prints comma-separated data in the form [block height, internal block timestamp, blockchain.info timestame, local machine timestamp] I only use the local timestamp''' f = open('c:\users\matt\desktop\log.txt', 'r') g = open('c:\users\matt\desktop\processed.txt', 'w') counter = 0 for line in f: print(str(getHeight(line)) + ',' + str(getReportedTime(line)) + ',' + str(getBlockchainTime(line)) + ',' + str(getMyTime(line))) g.write(str(getHeight(line)) + ',' + str(getReportedTime(line)) + ',' + str(getBlockchainTime(line)) + ',' + str(getMyTime(line)) +'\n') counter += 1 f.close() g.close() print(counter) main() # FILE 3: bitcoin_parser # -*- coding: utf-8 -*- """ Coded by Matt Springer This work is licensed under a Creative Commons Attribution 4.0 International License. """ from __future__ import print_function import csv def main(): indexArray = [] timeArray = [] with open('c:\users\matt\desktop\processed.txt', 'rb') as csvfile: reader = csv.reader(csvfile, delimiter=',') for row in reader: indexArray.append(int(row[0])) timeArray.append(int(row[3])) for index in range(len(timeArray)-1): '''the "if" statement rejects non-consecutive blocks''' if(indexArray[index + 1] == indexArray[index] + 1): print(indexArray[index], end=',') print(timeArray[index + 1] - timeArray[index]) main()