使用python定时抓取个人邮箱数据(通过邮件数量判断)

Posted Sky_Lannister

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用python定时抓取个人邮箱数据(通过邮件数量判断)相关的知识,希望对你有一定的参考价值。

在进行信息收集时,我们通常会使用电子邮件来接收最新的消息、文档、数据等资源。而在特定场景下,也有一些需要自动化获取和处理邮件数据的需求。在本篇博客中,我们将介绍如何使用Python的imaplib库连接到指定的邮箱服务器,获取最新的邮件数量,并下载最新的一封邮件并进行处理。

导入必要的库

在使用Python连接到邮箱服务器前,我们需要导入必要的库,包括imaplibemaildatetimetime库。其中,imaplibemail库用于连接到邮箱服务器、获取邮件数据和解析邮件内容,datetimetime库则用于日期格式转换和添加延时操作。

import imaplib
import email
import datetime
import time

获取最新的邮件数量

通过使用imaplib库连接到指定的邮箱服务器,我们可以使用以下代码获取最新的邮件数量:

def get_email_update(space):
    if DEBUG == 0:
        time.sleep(space)

    server = imaplib.IMAP4_SSL(remote_server_url, 993)
    server.login(email_url, password)
    server.select('INBOX')
    status, data = server.search(None, "ALL")
    if status != 'OK':
        raise Exception('read email error')
    emailids = data[0].split()
    mail_counts = len(emailids)
    current_time = datetime.datetime.now()
    current_time = current_time.strftime("%Y-%m-%d-%H:%M:%S")
    print(f'str(current_time)-邮件数量是 mail_counts')
    if mail_counts > qq_email_rx.count and qq_email_rx.count != 0 or DEBUG == 1:
        qq_email_rx.count = mail_counts
        return qq_email_rx.count
    else:
        qq_email_rx.count = mail_counts
        return 0

其中,get_email_update()函数接受一个参数space,表示每次检测邮件更新的间隔时间。在函数内部,首先使用time.sleep()方法添加延时操作,等待一定时间后再连接到邮箱服务器。通过使用IMAP4_SSL协议连接到指定的邮箱服务器,并使用server.login()方法登录。然后,选择INBOX文件夹,并使用search()方法搜索所有邮件。通过使用emailids = data[0].split()语句获取邮件ID列表,并使用len()方法获取最新的邮件数量。最后,将最新的邮件数量存储在qq_email_rx.count属性中,并返回该值。

需要注意的是,在调试模式下(即DEBUG标志位被设置为1),会打印所有信息,包括当前时间和邮件数量。如果没有新邮件更新,则会返回0。

下载并处理最新的邮件

在获取了最新的邮件数量后,我们可以使用以下代码下载最新的一封邮件,并进行后续处理:

def main_parse_Email(self):
    qq_email_rx.reset()
    qq_email_tx.reset()
    counts = email_parse.get_email_update(check_time)

    if counts == 0: #未更新
        return
    else:
        server = imaplib.IMAP4_SSL(self.remote_server_url, 993)
        server.login(self.email_url, self.password)
        server.select('INBOX')
        status, data = server.search(None, "ALL")
        if status != 'OK':
            raise Exception('read email error')
        emailids = data[0].split()
        mail_counts = counts

        status, edata = server.fetch(emailids[mail_counts-1], '(RFC822)')
        msg = email.message_from_bytes(edata[0][1])

        email_parse.get_email_title(msg) # 获取email title
        if qq_email_rx.From.find("叶绿素") == -1 and DEBUG == 0: # 不是指定邮箱的邮件
            print("不是指定邮箱发的文件")
            return
在`main_parse_Email()`方法中,我们首先调用`qq_email_rx.reset()`和`qq_email_tx.reset()`方法重置文件名和发送者地址。然后,使用`get_email_update()`函数获取最新的邮件数量,并将结果存储在`counts`变量中。如果没有新邮件更新,则直接返回;否则,继续连接到邮箱服务器,并使用`fetch()`方法下载最新的一封邮件。

该方法会将邮件消息转换为`message`对象,并调用`email_parse.get_email_title()`方法获取邮件标题。在这里,我们可以根据需求进行自定义操作,例如检查邮件发送者地址是否符合预期、下载邮件附件等。

需要注意的是,在此处我们使用了一个名为`email_parse`的模块,它包含了一些用于处理邮件数据的方法。在使用本代码之前,需要确保该模块已经正确导入并定义。

完整代码如下:

```python
import imaplib
import email
import datetime
import time

class EmailParser:
    def get_email_update(space):
        if DEBUG == 0:
            time.sleep(space)

        server = imaplib.IMAP4_SSL(remote_server_url, 993)
        server.login(email_url, password)
        server.select('INBOX')
        status, data = server.search(None, "ALL")
        if status != 'OK':
            raise Exception('read email error')
        emailids = data[0].split()
        mail_counts = len(emailids)
        current_time = datetime.datetime.now()
        current_time = current_time.strftime("%Y-%m-%d-%H:%M:%S")
        print(f'str(current_time)-邮件数量是 mail_counts')
        if mail_counts > qq_email_rx.count and qq_email_rx.count != 0 or DEBUG == 1:
            qq_email_rx.count = mail_counts
            return qq_email_rx.count
        else:
            qq_email_rx.count = mail_counts
            return 0

    def main_parse_Email(self):
        qq_email_rx.reset()
        qq_email_tx.reset()
        counts = email_parse.get_email_update(check_time)

        if counts == 0: #未更新
            return
        else:
            server = imaplib.IMAP4_SSL(self.remote_server_url, 993)
            server.login(self.email_url, self.password)
            server.select('INBOX')
            status, data = server.search(None, "ALL")
            if status != 'OK':
                raise Exception('read email error')
            emailids = data[0].split()
            mail_counts = counts

            status, edata = server.fetch(emailids[mail_counts-1], '(RFC822)')
            msg = email.message_from_bytes(edata[0][1])

            email_parse.get_email_title(msg) # 获取email title
            if qq_email_rx.From.find("叶绿素") == -1 and DEBUG == 0: # 不是指定邮箱的邮件
                print("不是指定邮箱发的文件")
                return

            # 下载邮件附件等操作
            # ...

            qq_email_rx.printf("接收")

            # 进行数据返回
            email_parse.email_back(qq_email_rx.filename)

if __name__ == '__main__':
    # 设置变量值
    remote_server_url = 'imap.qq.com'
    email_url = 'xxx6@qq.com'
    password = 'xxxx'
    check_time = 10
    DEBUG = 1

    # 创建对象并调用方法
    email_parse = EmailParser()

    while True:
        try:
            email_parse.main_parse_Email()
        except:
            print("error")
            traceback.print_exc()
            continue

在本代码中,我们首先定义了一些变量,包括远程邮箱服务器地址、邮箱地址和密码、检测更新的时间间隔和调试模式标志位。然后,创建了一个名为EmailParser的类,并定义了get_email_update()main_parse_Email()两个方法。其中,get_email_update()方法用于获取最新的邮件数量,main_parse_Email()方法用于下载最新的一封邮件并进行处理。

在使用时,我们创建了一个EmailParser对象,并调用了main_parse_Email()方法。可以根据需要修改相关变量值,例如将调试模式标志位设置为0,以关闭所有打印输出。

python邮件服务每天早上定时定时发送天气给邮箱

壹:获取天气api

打开和风天气https://console.heweather.com/,在注册和登陆之后,点击应用管理新建应用,创建key就会有下列实例。
在这里插入图片描述

一:api:

打开https://dev.heweather.com/docs/api/weather开发文档查看调用api

注意:分为免费版与商业版,一般我们个人使用只要用免费版就行了。
api:
1、现在:now(实况天气)
https://free-api.heweather.net/s6/weather/now?location=beijing&key=*******
2、预测:forecast(3-10天预报)
https://free-api.heweather.net/s6/weather/forecast?location=beijing&key=c49c31ad03b54c90b821af7c125ee0af
3、更多请看文档。。。

二:结果显示:

1、现在:now(实况天气)
{"HeWeather6":[{"basic":{"cid":"CN101010100","location":"北京","parent_city":"北京","admin_area":"北京","cnty":"中国","lat":"39.90498734","lon":"116.4052887","tz":"+8.00"},"update":{"loc":"2020-02-28 23:00","utc":"2020-02-28 15:00"},"status":"ok","now":{"cloud":"0","cond_code":"100","cond_txt":"晴","fl":"-1","hum":"80","pcpn":"0.0","pres":"1015","tmp":"2","vis":"15","wind_deg":"204","wind_dir":"西南风","wind_sc":"2","wind_spd":"9"}}]}
2、预测:forecast(3-10天预报)
{
    "HeWeather6": [
        {
            "basic": {
                "cid": "CN101010100",
                "location": "北京",
                "parent_city": "北京",
                "admin_area": "北京",
                "cnty": "中国",
                "lat": "39.90498734",
                "lon": "116.4052887",
                "tz": "+8.00"
            },
            "update": {
                "loc": "2020-02-28 22:57",
                "utc": "2020-02-28 14:57"
            },
            "status": "ok",
            "daily_forecast": [
                {
                    "cond_code_d": "100",
                    "cond_code_n": "101",
                    "cond_txt_d": "晴",
                    "cond_txt_n": "多云",
                    "date": "2020-02-28",
                    "hum": "67",
                    "mr": "09:12",
                    "ms": "22:21",
                    "pcpn": "0.0",
                    "pop": "0",
                    "pres": "1011",
                    "sr": "06:48",
                    "ss": "18:05",
                    "tmp_max": "8",
                    "tmp_min": "0",
                    "uv_index": "8",
                    "vis": "25",
                    "wind_deg": "239",
                    "wind_dir": "西南风",
                    "wind_sc": "1-2",
                    "wind_spd": "2"
                },
                {
                    "cond_code_d": "104",
                    "cond_code_n": "104",
                    "cond_txt_d": "阴",
                    "cond_txt_n": "阴",
                    "date": "2020-02-29",
                    "hum": "44",
                    "mr": "09:38",
                    "ms": "23:20",
                    "pcpn": "0.0",
                    "pop": "0",
                    "pres": "1016",
                    "sr": "06:46",
                    "ss": "18:06",
                    "tmp_max": "6",
                    "tmp_min": "1",
                    "uv_index": "1",
                    "vis": "25",
                    "wind_deg": "76",
                    "wind_dir": "东北风",
                    "wind_sc": "1-2",
                    "wind_spd": "7"
                },
                {
                    "cond_code_d": "101",
                    "cond_code_n": "100",
                    "cond_txt_d": "多云",
                    "cond_txt_n": "晴",
                    "date": "2020-03-01",
                    "hum": "33",
                    "mr": "10:06",
                    "ms": "00:00",
                    "pcpn": "0.0",
                    "pop": "0",
                    "pres": "1020",
                    "sr": "06:45",
                    "ss": "18:07",
                    "tmp_max": "11",
                    "tmp_min": "-3",
                    "uv_index": "4",
                    "vis": "25",
                    "wind_deg": "3",
                    "wind_dir": "北风",
                    "wind_sc": "1-2",
                    "wind_spd": "3"
                }
            ]
        }
    ]
}

三:参数说明

我使用的是3-10天天气预报数据,天气预报包含的数据:日出日落、月升月落、最高最低温度、天气白天和夜间状况、风力、风速、风向、相对湿度、大气压强、降水量、降水概率、露点温度、紫外线强度、能见度等数据

参数 描述 示例值
date 预报日期 2013-12-30
sr 日出时间 07:36
ss 日落时间 16:58
mr 月升时间 04:47
ms 月落时间 14:59
tmp_max 最高温度 4
tmp_min 最低温度 -5
cond_code_d 白天天气状况代码 100
cond_code_n 夜间天气状况代码 100
cond_txt_d 白天天气状况描述
cond_txt_n 晚间天气状况描述
wind_deg 风向360角度 310
wind_dir 风向 西北风
wind_sc 风力 1-2
wind_spd 风速,公里/小时 14
hum 相对湿度 37
pcpn 降水量 0
pop 降水概率 0
pres 大气压强 1018
uv_index 紫外线强度指数 3
vis 能见度,单位:公里 10

贰:使用python编写代码

全局变量:

url = \'https://free-api.heweather.net/s6/weather/{}?location={}&key={}\'
city1 = \'changsha\'
key = \'*****\'

这里使用同一个url来拼接来获取当前与预测的天气

一:获取当前天气

通过url获取当前的天气信息,并且转换为json数据。

def getNowWeather():
    \'\'\'
    获取现在天气的信息
    :return: 格式化后的数据
    \'\'\'
    res = json.loads(requests.get(url.format("now",city1,key)).text)
    location = res[\'HeWeather6\'][0][\'basic\']
    result = res[\'HeWeather6\'][0][\'now\']
    city = location[\'parent_city\'] + location[\'location\']
    cond_code = result[\'cond_code\']
    cond_txt = result[\'cond_txt\']
    tmp = result[\'tmp\']
    weather = {"city":city,"cond_txt":cond_txt,"cond_code":cond_code,"tmp":tmp}
    return weather

二:获取预测天气

获取的预测天气,得到的是天气数据转换为列表


def getForecastWeather():
    \'\'\'
    获取预测天气的信息
    :return: 格式化后的数据
    \'\'\'
    res = json.loads(requests.get(url.format("forecast",city1,key)).text)
    result = res[\'HeWeather6\'][0][\'daily_forecast\']
    weatherData = []
    for data in result:
        date = data[\'date\']
        cond_txt_d = data[\'cond_txt_d\']
        cond_code_d = data[\'cond_code_d\']
        tmp_max = data[\'tmp_max\']
        tmp_min = data[\'tmp_min\']
        sr = data[\'sr\']
        ss = data[\'ss\']
        weather = {"date":date,"cond_txt_d":cond_txt_d,"cond_code_d":cond_code_d,"tmp_max":tmp_max,"tmp_min":tmp_min,"sr":sr,"ss":ss}
        weatherData.append(weather)
    print(weatherData)
    return weatherData

三:发送邮件

首先,设置好域名、邮件标题,收发件人等信息。

    # 设置邮箱的域名
    HOST = \'smtp.qq.com\'
    # 设置邮件标题
    TITLE= \'lomtom发给你的今日份天气预报信息,请查收\'
    # 设置发件人邮箱
    FROM = \'发件人邮箱\'
    # 设置收件人邮箱
    TO = \'收件人邮箱\'		# 可以同时发送到多个邮箱,用逗号分开

然后,设置需要发送的信息,可以发一般的消息,我这里需要设置天气的样式,所以使用了html代码。

1、代码:
	mail_body = """这里是html代码"""
	message = MIMEText(mail_body, \'html\', \'utf-8\')
	
	# 设置邮件发件人
	message[\'From\'] = FROM
	# 设置邮件收件人
	message[\'To\'] = TO
	# 设置邮件标题
	message[\'Subject\'] = TITLE
    
2、message打印
    Content - Type: text / html;
    charset = "utf-8"
    MIME - Version: 1.0
    Content - Transfer - Encoding: base64
    From: 发件人邮箱
    To: 收件人邮箱
    com
    Subject: =?utf - 8?b?5L
    uK5pel5Lu95aSp5rCU6aKE5oql5L + h5oGv77yM6K + 35
    p + l5pS2?=
    CiAgICA8cD7kvaDlpb3vvIzov5nmmK / kuIDku73mtYvor5VweXRob27oh6rliqjlj5HpgIHpgq7k

样式:
样式
最后,设置邮件的相关信息并发送信息,一般来说,qq邮箱的端口为465,如果使用的是其他的邮箱,需要更换相应的端口。

    # 设置发件人邮箱的域名和端口,qq邮箱端口为465
    email_client = smtplib.SMTP_SSL(host=HOST,port=465)
    email_client.login(user=FROM,password=\'你自己的授权码\')
    email_client.sendmail(FROM, TO.split(\',\'),message.as_string())
    # 关闭邮件发送客户端
    email_client.close()

四:启动定时任务

python中有很多种方式来启动定时任务,我这里使用了schedule模块,我需要每天早上发送这个邮件,那么我需要设置一个定时任务,定时在每天早上七点半启动该任务,并且需要将schedule运行。

    # 每天在7:30的时候运行send_email
    schedule.every().days.at("13:05").do(send_email)
    while True:
        # 保持schedule一直运行,然后去查询上面的任务
        schedule.run_pending()

五:运行

ohup,使用nohup即可实现断开ssh连接命令也不会被终止。
一般我们可以在结尾加上"&"来将命令同时放入后台运行,也可用">new filename 2>&1"来更改缺省的重定向文件名。
用法:

1、后台运行
nohup python send_mail.py > send_mail.log 2>&1 &
2、查看进程
ps -ef | grep python
3、杀死进程
kill -s 9 27530

叁:效果图:

效果图

肆:作者有话

定时任务+邮箱服务这是不是很方便呢,在我们生活中,常需要这样的需求,作为单身的我们,每天定时给喜欢的人发送一条早安或者一条晚安信息,是不是很得女孩子的芳心呢,哈哈哈哈。


作者

1、作者个人网站
2、作者CSDN
3、作者博客园
4、作者简书

以上是关于使用python定时抓取个人邮箱数据(通过邮件数量判断)的主要内容,如果未能解决你的问题,请参考以下文章

python邮件服务每天早上定时定时发送天气给邮箱

利用 Python 自动抓取微博热搜,并定时发送至邮箱

电子邮件账户注册,注册个人邮箱功能集锦

定时发送邮件

# yyds干货盘点 # 手把手教你使用Python网络爬虫实现邮件定时发送(附源码)

#yyds干货盘点# 手把手教你使用Python网络爬虫实现邮件定时发送(附源码)