从 API 连续收集数据的最佳方法?
Best method of continuously collecting data from an API?
所以我有一个 python 脚本,它不断从 API 中收集数据,然后定期(例如每分钟)将它们保存到 excel 文件中。为此,我有一个 VPS 运行 代码 24/7。由于我需要来自多个来源的数据并且它们需要以不同的频率更新,我的解决方案是为每种类型的数据创建一个单独的函数,然后在单独的线程中调用所有这些函数。
举个例子:
def ExchangeRateCheck(self):
while True:
try:
self.exchangeRate = self.oanda.get_prices(instruments="AUD_USD").get('prices')[0]['ask']
except:
try:
self.exchangeRate = requests.get('http://free.currencyconverterapi.com/api/v3/convert?q=AUD_USD').json()['results']['AUD_USD']['val']
except:
pass
time.sleep(30)
ratethread = threading.Thread(target=self.ExchangeRateCheck, args=())
ratethread.daemon = True
ratethread.start()
考虑到无法到达 API 的时间,所有内容都嵌套在 try/except 子句中。然而,我发现有些线程仍会由于某些未知原因在某个时间点退出。
我的问题是:
对于这种类型的任务是使用远程 VPS 并在 while True 循环中分离函数的最佳解决方案吗?有没有更好的方法来收集 24/7 数据?我可以更好地处理异常以确保代码永不停止吗运行?
您可能会说我不是专业开发人员,因此非常感谢任何反馈,请随意对我施加压力,我不会生气。
这是"best"方式吗?那要看。老实说,您可以在一个线程中完成所有这些,但时间会因发出 http 请求所需的时间而略有不同。
不过,我确实有几点需要注意:
您正在使用 try / except,这很好,但您没有明确接受任何特定错误,这有点糟糕。您应该指定要接受哪些错误(例如无法连接到服务器、无效的 json 内容等)。
请记住,您还可以排除任何未知错误,并对它们执行其他操作,例如:
尝试:
do_something_here()
除了 MadeUpError 作为 e:
打印("Handled the made up error.")
除了异常为 e:
打印("Something unexpected happened: {}".format(e))
您正在使用守护线程。守护线程允许程序在不先停止它们的情况下退出。这意味着如果您的主线程退出,整个程序也应该退出。我认为这不是您想要的,并且由于您的程序 运行s 超过一秒钟然后退出,我假设您正在主线程中执行某些操作。您的数据检索工作者是守护进程是否有特定原因?
- 您没有停止程序的简单方法。您可以使用 threading.Event 而不是
while True:
。这是主线程可以设置的标志,例如,它希望所有工作人员退出。主线程可以 运行 尝试/除了 KeyboardInterrupt,并且在 except 处理程序中你可以 .set() 该事件,告诉工作人员在完成当前正在做的事情后退出。
- 如果您发现自己需要更复杂的调度(可能一个工作人员需要每 30 秒执行一次,另一个工作人员每 5 分钟执行一次,另一个每天 12:30 AM),您可以考虑使用诸如 APScheduler,专门设计用于 运行 在特定时间以一定间隔运行,并支持不同的调度程序(尽管您可能需要使用线程的 backgroundScheduler)。
- 您没有在我能看到的屏幕上使用任何类型的日志记录或打印。对于将要 运行 很长时间并且可能会遇到您稍后想知道的错误的内容,记录通常是个好主意。 Python 有一个标准库附带的很好的日志记录模块,它还有一个关于如何使用它的教程。您可以将日志消息发送到终端、文件、通过电子邮件等。有不同的日志记录级别,因此您可以将程序设置为仅将警告及以上内容打印到终端,而调试和信息消息不会打印出来。
希望对您有所帮助。
考虑通过将调度部分外部化来进一步简化它。您可以使用 cron 以不同的时间间隔和不同的参数(即数据源 URL)来 运行 您的脚本。这样你就可以自己避免编程并发问题。
所以我有一个 python 脚本,它不断从 API 中收集数据,然后定期(例如每分钟)将它们保存到 excel 文件中。为此,我有一个 VPS 运行 代码 24/7。由于我需要来自多个来源的数据并且它们需要以不同的频率更新,我的解决方案是为每种类型的数据创建一个单独的函数,然后在单独的线程中调用所有这些函数。
举个例子:
def ExchangeRateCheck(self):
while True:
try:
self.exchangeRate = self.oanda.get_prices(instruments="AUD_USD").get('prices')[0]['ask']
except:
try:
self.exchangeRate = requests.get('http://free.currencyconverterapi.com/api/v3/convert?q=AUD_USD').json()['results']['AUD_USD']['val']
except:
pass
time.sleep(30)
ratethread = threading.Thread(target=self.ExchangeRateCheck, args=())
ratethread.daemon = True
ratethread.start()
考虑到无法到达 API 的时间,所有内容都嵌套在 try/except 子句中。然而,我发现有些线程仍会由于某些未知原因在某个时间点退出。
我的问题是: 对于这种类型的任务是使用远程 VPS 并在 while True 循环中分离函数的最佳解决方案吗?有没有更好的方法来收集 24/7 数据?我可以更好地处理异常以确保代码永不停止吗运行?
您可能会说我不是专业开发人员,因此非常感谢任何反馈,请随意对我施加压力,我不会生气。
这是"best"方式吗?那要看。老实说,您可以在一个线程中完成所有这些,但时间会因发出 http 请求所需的时间而略有不同。
不过,我确实有几点需要注意:
您正在使用 try / except,这很好,但您没有明确接受任何特定错误,这有点糟糕。您应该指定要接受哪些错误(例如无法连接到服务器、无效的 json 内容等)。 请记住,您还可以排除任何未知错误,并对它们执行其他操作,例如:
尝试: do_something_here() 除了 MadeUpError 作为 e: 打印("Handled the made up error.") 除了异常为 e: 打印("Something unexpected happened: {}".format(e))
您正在使用守护线程。守护线程允许程序在不先停止它们的情况下退出。这意味着如果您的主线程退出,整个程序也应该退出。我认为这不是您想要的,并且由于您的程序 运行s 超过一秒钟然后退出,我假设您正在主线程中执行某些操作。您的数据检索工作者是守护进程是否有特定原因?
- 您没有停止程序的简单方法。您可以使用 threading.Event 而不是
while True:
。这是主线程可以设置的标志,例如,它希望所有工作人员退出。主线程可以 运行 尝试/除了 KeyboardInterrupt,并且在 except 处理程序中你可以 .set() 该事件,告诉工作人员在完成当前正在做的事情后退出。 - 如果您发现自己需要更复杂的调度(可能一个工作人员需要每 30 秒执行一次,另一个工作人员每 5 分钟执行一次,另一个每天 12:30 AM),您可以考虑使用诸如 APScheduler,专门设计用于 运行 在特定时间以一定间隔运行,并支持不同的调度程序(尽管您可能需要使用线程的 backgroundScheduler)。
- 您没有在我能看到的屏幕上使用任何类型的日志记录或打印。对于将要 运行 很长时间并且可能会遇到您稍后想知道的错误的内容,记录通常是个好主意。 Python 有一个标准库附带的很好的日志记录模块,它还有一个关于如何使用它的教程。您可以将日志消息发送到终端、文件、通过电子邮件等。有不同的日志记录级别,因此您可以将程序设置为仅将警告及以上内容打印到终端,而调试和信息消息不会打印出来。
希望对您有所帮助。
考虑通过将调度部分外部化来进一步简化它。您可以使用 cron 以不同的时间间隔和不同的参数(即数据源 URL)来 运行 您的脚本。这样你就可以自己避免编程并发问题。