只要满足给定计算机的阈值,就从Python脚本发送电子邮件?

时间:2014-05-01 17:43:23

标签: python json parsing smtp

我有一个URL,如果我在浏览器上点击它,它会给我下面的JSON字符串 -

以下是我的网址,假设它是URL-A,我有三个这样的网址 -

http://hostnameA:1234/Service/statistics?%24format=json

以下是我从网址回来的JSON字符串 -

{
 "description": "",
 "statistics": {
  "dataCount": 0,
 }
}

现在我编写了一个Python脚本,它扫描我的所有3个URL,然后再解析JSON String以从中提取dataCount的值。并且应该每隔几秒钟继续运行以扫描URL,然后解析它。

以下是我的网址

hostnameA       http://hostnameA:1234/Service/statistics?%24format=json
hostnameB       http://hostnameB:1234/Service/statistics?%24format=json
hostnameC       http://hostnameC:1234/Service/statistics?%24format=json

在运行我的python脚本后,我在控制台上看到的数据是这样的 -

hostnameA - dataCount
hostnameB - dataCount
hostnameC - dataCount

下面是我的python脚本,它可以正常工作

def get_data_count(url):
    try:
        req = requests.get(url)
    except requests.ConnectionError:
        return 'could not get page'

    try:
        data = json.loads(req.content)
        return int(data['statistics']['dataCount']) 
    except TypeError:
        return 'field not found'
    except ValueError:
        return 'not an integer'

def send_mail(data):
    sender = 'user@host.com'
    receivers = ['some_name@host.com']

    message = """\
From: user@host.com
To: some_name@host.com
Subject: Testing Script
"""    
    body = '\n\n'
    for item in data:
        body = body + '{name} - {res}\n'.format(name=item['name'], res=item['res'])

    message = message + body

    try:
       smtpObj = smtplib.SMTP('some_server_name' )
       smtpObj.sendmail(sender, receivers, message)
       print "Mail sent"
    except smtplib.SMTPException:
       print "Mail sending failed!"

def main():
        urls = [
            ('hostnameA', 'http://hostnameA:1234/Service/statistics?%24format=json'),
            ('hostnameB', 'http://hostnameB:1234/Service/statistics?%24format=json'),
            ('hostnameC', 'http://hostnameC:1234/Service/statistics?%24format=json')
        ]

    count = 0
    while True:
        data = []
        print('')

        for name, url in urls:
            res = get_data_count(url)
            print('{name} - {res}'.format(name=name, res=res))
            data.append({'name':name, 'res':res})

        if len([item['res'] for item in data if item['res'] >= 20]) >= 1: count = count+1
        else: count = 0

        if count == 2: 
            send_mail(data)
            count = 0
        sleep(10.)

if __name__=="__main__":
    main()

我也在使用上面的脚本,假设任何机器dataCount值连续两次大于等于20,那么我发送一封电子邮件,它也是工作正常。

我注意到的一个问题是,假设hostnameB因任何原因而失效,那么它将首次打印出来 -

hostnameA - 1
hostnameB - could not get page
hostnameC - 10

第二次它也会打印出来 -

hostnameA - 5
hostnameB - could not get page
hostnameC - 7

因此,我的上述脚本也发送了针对此案例的电子邮件,因为could not get page连续两次但实际上hostnameB dataCount值不大于等于20两次?对?所以我的脚本中有一些错误,不知道如何解决?

如果任何主机名dataCount值连续两次大于等于20,我只需要发送一封电子邮件。如果机器由于某种原因而停机,那么我将跳过这种情况,但我的脚本应继续运行。

2 个答案:

答案 0 :(得分:1)

您应该使用False来表示失败的请求,而不是字符串"could not get page"。这样会更干净,但如果将False值视为int,则0值也会加倍>>> True + False 1

False

总结两个或多个0值将等于{{1}}。

答案 1 :(得分:1)

不更改get_data_count功能:

我冒昧地使用服务器名称作为索引来创建数据字典,这使得查找最后一个值更容易。

我存储了最后一个字典,然后将当前值和旧值比较为20。大多数字符串都是> 19,所以我从结果中创建一个int对象,当结果是一个字符串时会抛出异常,然后我可以再次捕获它以防止关闭服务器被计数。

last = False

while True:
    data = {}
    hit = False
    print('')

    for name, url in urls:
        res = get_data_count(url)
        print('{name} - {res}'.format(name=name, res=res))
        data[name] = res
        try:
            if int(res) > 19:
                hit = True
        except ValueError:
            continue

    if hit and last:
            send_mail(data)
    last = hit
    sleep(10.)

Pong Wizard是对的,你不应该处理那样的错误。要么返回FalseNone并稍后引用该值,要么只是抛出异常。