已经完成了利用python爬虫实现定时QQ邮箱推送英文文章,辅助学习英语的项目,索性就一口气利用python多做一些自动化辅助英语学习的项目,对自己的编程能力和英文水评也有一定的帮助,于是在两天的努力下,我完成了今天的项目。

首先是艾宾浩斯记忆法,大家了解一下真的非常有效果(至少对于我来讲啦┑( ̄Д  ̄)┍)

当然,我也会把自己的项目上传到github上供大家指正,由于本人非常喜欢python和英语,所以后期也做很多将两者结合起来的项目。所以,如果大家对本项目有兴趣,希望体验或加入开发,又或者对它有一定的想法与意见,欢迎加入我最近组建的交流群。谢谢大家啦~~

https://qm.qq.com/cgi-bin/qm/qr?k=yWHTRdPppmHE_YiNeTbTlCtqiD2qPm97&authKey=2tcLazZwqjqHuUpnrpJR2DalP/izfPw9xw7g6CQnZHYe9ZEoB4p0kbkgQ/aSa/nq (二维码自动识别)

本项目主要是通过在事先准备好的excel单词文件中每天抽取单词,并反复使用QQ邮箱发送到自己的邮箱里提醒自己有一定规律的背单词,项目最大的难点有三。


  1. 对于csv文件的对应切片任务等操作
  2. 对于日志的记录
  3. 艾宾浩斯记忆法是一个周期性的过程,需要反复的计算。

当然,由于这个项目的文件还是比较多的,所以为了简化这个项目,我就先按照自己的开发思路来说,当然如果要自己来使用本项目还是要费一番心思读一读代码才好,因为在dataframe数据的处理部分随便拿一个小坑讲一下都是一篇文章( )所以,各位一定要耐心读下去鸭。


好了 show me the code


开发环境 :python3.6 IDEA : pycharm2019 阿里云ECS: centos7

接下来我们看一下项目路径,并注意对应进行解释: (忽略我拙略的变量英文,就是因为这样所以才好好学习英语鸭)


分别来解释一下

data 目录: 用于存放日志文件,分别有data_log.csv和word.csv data_log.csv 用于每天随机抽取单词的时候避免抽取到重复的单词。 word.csv 是每天将每个单词的time时间数据记录进去进而用于计算单词复习的时间。


*every_day_word* 目录: 用于存储每天随机抽取的单词机器词义等相关信息,并将其存储为csv格式,以对应的时间为文件名存储,同步在上面的data_log.csv的time索引内。

___ word 目录 : 存储总的单词大表数据的目录,很简单。


接下来就是我们的项目代码部分,如你所见项目代码都在项目的根目录处,

接下来我会一 一的说明这些代码,当然是以我自己的顺序,对了代码的详细解释在代码的注释里面,有任何疑问和想法可以加入上面的群来交流。


word_read_project.py


这一部包含了多个函数与变量,是项目文件处理的第一核心部分,主要难点在于dataframe的控制问题以及日志的读写问题,需要耐心的看完,推荐搭配pycharm专业版使用,非常方便。

#auther :keepython
import pandas as pd
import numpy as np
import os
import time
import randomword_file_path = 'word/六级核心词汇表(EXCEL表格).xls'
data_log_path = 'data/data_log.csv'
# data_log = pd.read_csv(data_log_path)
words = pd.read_excel(word_file_path,header=0)
# print(len(words)+1)#求出一共多少列,从1开始算
# print(words.columns)#列索引名称
# print(words.index)#行索引名称words_index = words.index#函数功能:传入随机生成的单词索引,返回单词dataframe相关信息
def find_word(random_word_index,words):print(type(random_word_index))#根据随机单词的索引导出单词的相关信息random_words = words.loc[list(random_word_index)]# print(random_words)return random_words#函数功能: 在进行random_80函数操作以后对word.csv进行同步记录,注意传进来的必须是列表的形式
def word_csv_log(random_words,time_stamp):word_path = 'data/word.csv'word_log = pd.read_csv(word_path,index_col=0)#读取单词日志文件,同时将索引设置为对应的时间for random_word in random_words:#将对应的随机抽取的单词5min,30min,12hour分别标记为1word_log.loc['time'][random_word] = time_stampword_log.iloc[0:3][random_word][0] = 1word_log.iloc[0:3][random_word][1] = 1word_log.iloc[0:3][random_word][2] = 1word_log.to_csv(word_path)print('标记完成'.center(40,'='))#函数功能:读取日志已经选择的单词索引内容返回列表
def data_log_read(data_log_path):data_logs = pd.read_csv(data_log_path)data_log_index = np.array(data_logs).tolist()return data_log_index#函数功能:通过索引提取dataframe中的行,返回对应的dataframe数据方便生成csv文件
def random_80_word_to_csv(random_index,words):random_80_word_df = words.iloc[random_index,:]return random_80_word_df#函数功能:随机从传入的单词索引列表中抽取80个词
def random_80_word(words_indexs,words):data_log_path = 'data/data_log.csv'# print(type(words_index))#显示传入索引格式try:data_log_index = data_log_read(data_log_path)#返回日志中的索引words_index = [i for  i in words_indexs if i not in data_log_index]except :words_index= list(words_indexs)random_word = random.sample(list(words_index),80)#同时记录被选中的索引数据print(len(random_word))random_words = find_word(random_word,words)[['单词']]random_words = np.array(random_words).tolist()#这里是列表嵌套的形式需要解套random_words = [i[0] for i in random_words]#将随机抽取的#time模块的使用还要考虑到后面everyday_word.csv文件命名的问题,文件名称中不能有特殊符号time_stamp = time.strftime("%Y-%m-%d-%H-%M", time.localtime())#使用time模块以对应的年-月-日-小时-分钟的形式返回的数据为字符串every_day_word_path = 'every_day_word/'+str(time_stamp)+'.csv'random_80_word_df = random_80_word_to_csv(random_word,words)#在这一步调用函数同时生成对应random文件数据word_csv_log(random_words,time_stamp)print(type(random_80_word_df))random_80_word_df.to_csv(every_day_word_path)data = {time_stamp: random_word}#用于data_log.csv路径不存在情况if os.path.exists(data_log_path):#将今天生成的随机单词存入日志csv文件中备用datas = pd.read_csv(data_log_path)datas.loc[:, str(time_stamp)] = pd.Series(random_word)# datas[time_stamp] = random_word #注意,由于日期的原因无法输入列索引相同的数据,dataframe本质有点像优化的数据库datas.to_csv(data_log_path,index=False)#注意这里的mode的设置,必须设置为覆盖模式else:datas = pd.DataFrame(data)datas.to_csv(data_log_path, index=False)return random_word,every_day_word_path#将随机索引的80个词返回random_word_index,every_day_word_path = random_80_word(words_indexs=words_index,words= words)
# print(random_word_index)random_words_df = find_word(random_word_index,words)#返回的依然是dataframe格式的数据
# print(type(random_words))#返回索引到的单词数据用于建立日期表
random_words = random_words_df[['单词']]#对列进行操作这里还是dataframe格式
random_words_lists = np.array(random_words).tolist()#注意这里的random_words_list每一个random_word都是单独的列表,迭代时需要[0]for random_word in random_words_lists:print('今日随机单词'.center(80,'='))print(random_word[0])
#这里借助numpy将dataframe转换为list格式方便后面进行文件重组时间文件#word_read_pro.py的最终目的就是提供80个随机单词,不具备判断能力,但是记录随机筛选的单词的索引#在随后的返回函数中根据csv时间文件判断是否需要call_back
# random_words_lists = np.array(random_words).tolist()#注意这里的random_words_list每一个random_word都是单独的列表,迭代时需要[0]


temp_word_write_pro.py

暂时文件读写模块 主要用于将word中的单词数据转化为data日志的方式,方便后面的存储与数据处理。这一模块需要单独运行,可以在部署服务器之前运行一遍就好,当然还是要注意centos7的绝对路径的问题。 show me the code

# auther : keepython
import pandas as pd
import numpy as np
import random
file_name = '六级核心词汇表(EXCEL表格)'
word_file_path = '/word_recording_project/word/' + file_name+'.xls'
words = pd.read_excel(word_file_path,header=0)
words_index = words.indexwords = words[['单词']]
print(len(np.array(words).tolist()))
words = np.array(words).tolist()#将所有单词转换为列索引,行索引转换为天数
print(len(words))
datas = {}
for word in words :datas[word[0]] = {"5min":0,"30min":0,'12hour':0,'day1':0,'day2':0,'day4':0,'day7':0,'day15':0,'time':'1111-11-11-11-11'}words_df = pd.DataFrame(data=datas)
print(words_df)
words_df.to_csv('/word_recording_project/data/word.csv')
# print(words_df)

every_day_count_pro.py

这一部分从标题来看就是用于对every_day_word中的文件与data中的日志文件配合计时并返回对应的文件路径用于后面的邮件发送调用。

import time
import datetime
import pandas as pd
import numpy as np
from  word_read_project import every_day_word_path
from mail_send_project import mail_send_fuc#函数功能:负责time时间的相减,并分别返回时间间隔时间为1day 2day 4day 7day 15day 的路径列表
def read_log_remind():word_log_path = '/word_recording_project/data/word.csv'word_log = pd.read_csv(word_log_path,index_col=0)word_log = word_log.Tword_log = word_log[word_log.time != '1111-11-11-11-11']  # 提取word.csv文件中time所有不等于‘1111-11-11-11-11’的模块#将矩阵转置方便使用index提取路径time_stamp = time.strftime("%Y-%m-%d-%H-%M", time.localtime()).split('-')log_times = np.array(word_log['time']).tolist()today = datetime.datetime(int(time_stamp[0]),int(time_stamp[1]),int(time_stamp[2]),int(time_stamp[3]),int(time_stamp[4]))#分别设置对应天数的路径列表day_1_path = []day_2_path = []day_4_path = []day_7_path = []day_15_path = []for log_time in log_times:log_timed = log_time.split('-')# print(log_timed)last_day = datetime.datetime(int(log_timed[0]),int(log_timed[1]),int(log_timed[2]),int(log_timed[3]),int(log_timed[4]))reduce = today - last_day#用于判断天数if reduce.days == 1:path  = '/word_recording_project/every_day_word/'+log_time+'.csv'day_1_path.append(path)elif reduce.days == 2:path = '/word_recording_project/every_day_word/' + log_time+'.csv'day_2_path.append(path)elif reduce.days == 4:path = '/word_recording_project/every_day_word/' + log_time+'.csv'day_4_path.append(path)elif reduce.days == 7:path = '/word_recording_project/every_day_word/' + log_time+'.csv'day_7_path.append(path)elif reduce.days == 15:path = '/word_recording_project/every_day_word/' + log_time+'.csv'day_15_path.append(path)#列表收集完路径后还需要去重day_1_path = list(set(day_1_path))day_2_path = list(set(day_2_path))day_4_path = list(set(day_4_path))day_7_path = list(set(day_7_path))day_15_path = list(set(day_15_path))return day_1_path,day_2_path,day_4_path,day_7_path,day_15_path#负责当天的推进5 min 30 min 12小时
def today_word_count():today_path = every_day_word_pathprint('今日要推送的地址是: ',today_path)time_stamp = time.strftime("%Y-%m-%d", time.localtime())subject = '艾宾浩斯 '+time_stamp+' 第一次单词提醒'mail_send_fuc(today_path,subject)time.sleep(300)#5min提醒mail_send_fuc(today_path,subject)time.sleep(1500)#30min提醒mail_send_fuc(today_path,subject)time.sleep(41400)#12小时提醒mail_send_fuc(today_path,subject)

mail_send_project.py

邮件发送,输入邮件主题和对应的附件路径直接发送,注意使用的时候修改一下对应的一些变量。

import smtplib
from email.header import Header
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
#从word.csv文件传入文件everyday文件路径就可以直接发送邮件
# everyday_file_path = '2020-02-02.csv'#函数功能:传入附件路径,邮件的主题发送邮件并返回发送状态def mail_send_fuc(everyday_file_path,subject):message = MIMEMultipart()msg_from = '***********'  # 发送方邮箱地址。password = '***************'  # 发送方QQ邮箱授权码,不是QQ邮箱密码。msg_to = '*************'msg_to_1 = '******************'  # 收件人邮箱地址。message = MIMEMultipart()message['From'] = msg_from  # 发送者message['To'] = msg_to  # 接收者# 邮件标题message['Subject'] = Header(subject, 'utf-8')# 邮件正文内容message.attach(MIMEText('艾宾浩斯根据你的遗忘曲线提醒单词'.center(20,'+'), 'plain', 'utf-8'))#打开文件part = MIMEApplication(open(everyday_file_path, 'rb').read())part.add_header('Content-Disposition', 'attachment', filename=everyday_file_path)message.attach(part)#添加文件try:client = smtplib.SMTP_SSL('smtp.qq.com', smtplib.SMTP_SSL_PORT)print("连接到邮件服务器成功")client.login(msg_from, password)print("登录成功")client.sendmail(msg_from, msg_to, message.as_string())print("发送成功")except smtplib.SMTPException as e:print("发送邮件异常")finally:client.quit()# mail_send_fuc(everyday_file_path)


main_code.py

调用所有模块和函数,将之组合起来实现最终的功能。项目在调用的时候也只需要调用main_dode.py就可以了。

import pandas as pd
import numpy as np
import os
import time
import random
from every_day_count_pro import *#总的执行函数包括写入word.csv日志的功能if __name__ == '__main__':day_1_paths, day_2_paths, day_4_paths, day_7_paths, day_15_paths = read_log_remind()today_word_count()time.sleep(3600)#1小时后再复习昨天的知识if len(day_1_paths) != False:for day_1_path in day_1_paths:subject = '1 天前的单词复习'.center(20,'=')mail_send_fuc(day_1_path,subject)time.sleep(900)if len(day_2_paths) != False:for day_2_path in day_2_paths:subject = '2 天前的单词复习'.center(20,'=')mail_send_fuc(day_2_path,subject)time.sleep(900)if len(day_4_paths) != False:for day_4_path in day_4_paths:subject = '4 天前的单词复习'.center(20,'=')mail_send_fuc(day_4_path,subject)time.sleep(900)if len(day_7_paths) != False:for day_7_path in day_7_paths:subject = '4 天前的单词复习'.center(20,'=')mail_send_fuc(day_7_path,subject)time.sleep(900)if len(day_15_paths) != False:for day_15_path in day_15_paths:subject = '15 天前的单词复习'.center(20,'=')mail_send_fuc(day_15_path,subject)


项目到这里就算开发完成啦,注意这里面的dataframe数据的操作真的非常高效,但是坑也很多希望有需要的同学一定要认真看。┑( ̄Д  ̄)┍


服务器定时任务部署

这一部分一定要修改好代码里面对应的路径,还是那句话centos7里面的绝对路径的问题。

编辑crontab配置这一步详细解释可以看这里:

Linux-Centos 用crontab定时运行python脚本详细步骤

crontab -e

编写配置文件

当打开配置文件的时候,我们可以看到类似的配置代码。每一行都代表一个定时任务 , 我们要做的就是新添加一行配置代码。

重启服务

service crond restart

最终就完成啦

欢迎留言交流学习,有什么疑问也可以交流,如果聊的开心还可以多一个朋友。

python随机抽取人名_python实现艾宾浩斯背单词功能,实现自动提取单词、邮件发送,再也不用担心背单词啦...相关推荐

  1. python随机抽取人名_python的random

    python的random函数 更多的random用法可参阅: random --- 生成伪随机数 - Python 3.7.4 文档​docs.python.org 以下使用了: 洗牌:random ...

  2. python随机抽取人名_用Python打造一个CRM系统(五)

    在上一篇上实现了线索功能模块,在实际使用中除了线索数据除了输入的结构化数据,也有可能是来自非结构化数据,如名片.PDF文档.语音视频等.为方便线索录入,本篇中将以名片为例,实现利用OCR等技术将名片信 ...

  3. 【Python小案例】打工人必备:有了这款倒计时神器,再也不用担心自己的隐私被偷窥啦~(附源码)

    前言 又见面了,小伙伴儿们,发现最近大家喜欢看一些简单的小案例?! 咳咳,下面进入正题. 每个人的电脑里都会有不想让别人知道的隐私,或者是上班时间偷偷摸鱼怕被发现的小秘密. 那怎么办?就干脆把隐私锁起 ...

  4. python用于pmc排产可以吗_用这个方法做好PMC管理,再也不用担心企业生产管理出现问题啦...

    PMC的概念及其重要性 PMC是 Production Material Control 的缩写,意思是生产与物料控制,主要包括两个部分: 1)PC,即生产管控,PC人员的职责包括制定生产规划并将计划 ...

  5. python实现抢劵_用Python实现微信自动化抢红包,再也不用担心抢不到红包了

    1. 概述 刚刚收到了两个消息,一个好消息,一个坏消息. 先说好消息,好消息就是微信群里有人要发红包,开心~ 不过转念一想,前几次的红包一个都没抢到,这次???不由自主的叹了一口气 ... 过了一会, ...

  6. python绘制横向柱状图 妈妈再也不用担心我不会画图了

    python绘制横向柱状图 妈妈再也不用担心我不会画图了 前言 实现代码 成果 前言 事情要从一次画图开始说起 当我开开心心搞到一堆数据,以为能够休息的时候,这时候我突然想起来,是不是绘制成柱状图更直 ...

  7. python随机抽号_Python 随机从字典中抽取数据

    写bug的代码小白 随机从字典中抽取数据 import random listb = {1: '张三', 2: '李四', 3: '王五', 4: '赵六', 5: '王麻子', 6: '包子', 7 ...

  8. python随机抽取5张扑克牌,判断是否为顺子

    废话不多说,直接上代码,都有注释: """ 编程语言:python 3.6 系统环境:window10 如果A设置为1,J=11, Q=12, K=13, 大小王设置为0 ...

  9. mysql题库随机抽取试题_Python从MySQL数据库中面抽取试题,生成试卷

    一.背景 本文章主要是分享如何使用Python从MySQL数据库中面抽取试题,生成的试卷每一份都不一样. 二.准备工作 1.安装Python3 2.安装库 pip install python-doc ...

最新文章

  1. 云栖大会看技术人成长之路
  2. vrrp虚拟路由冗余协议简图
  3. mock模拟接口测试 vue_Easy Mock以及Vue+Mock.js模拟数据
  4. .net post提交后接收返回数据_读完这一篇IT程序员终于明白post和get的区别
  5. 汇总丨MySQL GTID技术点,看这一篇就够了!
  6. Mac下gradle简介与安装
  7. EntityFrameworkCore DBFirst
  8. 基于SNMP网络管理系统的实现
  9. C语言拯救者 番外篇 (Windows实用调试技巧)
  10. taskmgr(任务管理器)无法出来的解决办法
  11. 【PyG】简介 - 图神经网络
  12. python代替云打码的超级鹰验证码识别第三方工具使用分享
  13. C语言 写一个函数求两个数的较大值
  14. python爬虫——利用超级鹰识别验证码并进行古诗网进行模拟登录
  15. python 期货现货差价监测_期货现货价差小工具——天勤量化(TqSdk)
  16. Apriori算法及例题
  17. MyStack<T>
  18. python——赋值
  19. keras实现seq2seq做Chatbot
  20. 使用python3查收与发送邮件

热门文章

  1. MicroProfile OpenAPI上的Swagger UI
  2. 怎么简单的锁定文件夹_简单性与鲁棒性–在锁定文件处理中展示
  3. Spring JPA数据+Hibernate+ MySQL + Maven
  4. 使用虚拟时间测试基于时间的反应堆堆芯流
  5. 在Spring MVC中,InternalResourceViewResolver做什么?
  6. 学习Spring-Cloud –编写微服务
  7. 针对新手的Java EE7和Maven项目–第1部分–简单的Maven项目结构–父pom
  8. Java方法中的参数太多,第6部分:方法返回
  9. jclouds的命令行界面
  10. 用于Spring应用程序的Gradle原型