如何在脚本运行之间存储对象?

时间:2018-01-29 12:27:32

标签: python

我正在使用基于此Mint API的python脚本来每小时提取个人财务信息。

要连接到Mint,我会mint = mintapi.Mint(email, password)通过selenium打开Chrom实例并登录到Mint,并创建一个<class 'mintapi.api.Mint'>

的对象

要刷新信息,我只需要mint.initiate_account_refresh()

但每次我运行脚本时,它都会再次记录整个事件。

我可以以某种方式将mint对象存储在磁盘上,以便我可以跳过该步骤并只刷新帐户吗?

3 个答案:

答案 0 :(得分:1)

  

要在Python中存储对象,您可以使用pickle模块。

假设您有一个对象mint

import pickle
mint = Something.Somefunc()

with open('data.pickle','wb') as storage:
    pickle.dump(mint,storage)

该对象将被保存为名为data.pickle的文件中的二进制字节序列。

要访问它,只需使用pickle.load()功能。

import pickle

with open('data.pickle','rb') as storage:
    mint = pickle.load(storage)

>>>mint
>>><class 'something' object>

注意:

  

虽然这里没关系但是pickle模块有一个缺陷,它可以在从文件加载时执行一些函数对象,所以在从第三方源读取pickle存储对象时不要使用它。

答案 1 :(得分:1)

开源的奇迹啊。

好奇,我去看了你链接的mintapi,看看是否有任何明显和简单的事情可以重新创建对象实例而不需要艰苦的设置。

事实证明并非如此。 :(

以下是实例化Mint对象时调用的内容:

def __init__(self, email=None, password=None):
    if email and password:
        self.login_and_get_token(email, password)

正如你所看到的,如果你没有给它一个真实的emailpassword,它就什么都不做。 (作为旁注,它应该真的正在检查is None,但无论如何。

因此,我们可以避免很容易地完成设置过程,但现在我们需要找出如何根据以前的数据伪造设置过程。

查看.login_and_get_token(),我们会看到以下内容:

def login_and_get_token(self, email, password):
    if self.token and self.driver:
        return

    self.driver = get_web_driver(email, password)
    self.token = self.get_token()

又好又简单。如果它已经有一个令牌,那就完成了,所以它就消失了。如果没有,则设置驱动程序,并通过调用.token设置.get_token()

这使得整个过程非常容易覆盖。只需实例化一个没有参数的Mint对象:

mint = mintapi.Mint()

然后在其上设置.token

mint.token = 'something magical'

现在你有一个处于几乎就绪状态的对象。问题是它基本上依赖于self.driver每个方法调用,包括您的.initiate_account_refresh()

def initiate_account_refresh(self):
    self.post(
        '{}/refreshFILogins.xevent'.format(MINT_ROOT_URL),
        data={'token': self.token},
        headers=JSON_HEADER)

...

def post(self, url, **kwargs):
    return self.driver.request('POST', url, **kwargs)

这似乎是一个简单的POST,我们可以用requests.post()调用取而代之,但我怀疑看到它是通过网络浏览器进行的,它依赖于某种形式的cookie或会话存储

如果你想进行实验,你可以像这样继承Mint

class HeadlessMint(Mint):

    def post(self, url, **kwargs):
        return requests.post(url, **kwargs)

但我的猜测是,随着时间的推移会出现更多问题。

好消息是这个mintapi项目看起来相当简单,并且重写它不依赖于网络浏览器对于经验不足的人来说看起来不是一个不合理的项目,所以请保持在你的背后口袋。

至于酸洗,我不相信这会起作用,因为我不相信子类化的原因 - 我认为浏览器的存在很重要。即使您挑选了mint实例,当您尝试加载它时,它也会丢失其浏览器。

最简单的解决方案很可能是让脚本长时间运行,而不是每小时运行一次,运行一次,然后执行它所需要的,然后睡觉一个小时,然后再做一次。这样,您可以在一开始就登录一次,然后只要它正在运行就可以保持该会话。

答案 2 :(得分:0)

使用库pickle保存并加载对象

保存

import pickle

mint = mintapi.Mint(email, password)
with open('mint .pkl', 'wb') as output:
    pickle.dump(mint , output, pickle.HIGHEST_PROTOCOL)

<强> LOAD

import pickle

with open('mint.pkl', 'rb') as input:
    mint= pickle.load(input)

mint.initiate_account_refresh()