文章目录

  • 一、概述
  • 二、模块重新划分
  • 三、优化定时任务
  • 四、发送邮件
  • 五、源代码

一、概述

上一篇文章python-定时爬取指定城市天气(一)-发送给关心的微信好友中我们讲述了怎么定时爬取城市天气,并发送给指定微信好友,文末遗留两个问题

  • 定时任务做成windows服务,这样更优雅,随开机启动
  • 发送消息给微信好友换成发送邮件给指定邮箱

本篇文章我们在原来代码的基础上进行了一定的模块拆分,并处理以上两个问题

二、模块重新划分

1、 新增my_job.py文件,把任务模块单独划分出来

之前的定时任务使用的是apscheduler库做的,并且任务类在main函数所在py文件中,这样导致主py文件很难进行修改

2、 新增util.py文件

包含公用的方法,比如目前的字典转字符串

3.、新增weather_service.py文件

主要负责构造windows服务,也是一个主py文件,不同于第一篇文章的主py文件weath_report.py,这是我们实现的两种定时任务,可分别运行,如果想把天气信息通知微信好友则启动weath_report.py,可参考文章ython-定时爬取指定城市天气(一)-发送给关心的微信好友,如果是通过发送邮件的方式则直接把weather_service.py安装成windows服务,并启动即可,记住需要配置运行的任务列表,下边会讲述怎么配置任务

4、 新增timing_task.py文件

包含任务方法executeJob(),主要是在服务中循环跑,然后在合适的时间爬取天气并发送到指定邮箱,任务的参数是通过配置json串来实现

三、优化定时任务

本篇文章的定时任务是运行在windows服务中的,因此我们首先需要安装pywin32模块

1.、安装pywin32

pip install pywin32

2.、服务操作相关命令

1.安装服务 python PythonService.py install
2.让服务自动启动 python PythonService.py --startup auto install
3.启动服务 python PythonService.py start
4.重启服务 python PythonService.py restart
5.停止服务 python PythonService.py stop
6.删除/卸载服务 python PythonService.py remove

3.、启动服务时被拒绝

Installing service timingTaskDaemon
Error installing service: 拒绝访问。 (5)

a.大多数原因是由于python环境配置的问题,python默认安装时配置的pah是用户环境变量,这里我们需要改成系统环境变量,具体可以参考Python 写windows service 及 start service 出现错误 1053:服务没有及时响应启动或控制请求
b.考虑命令行是否有权限,我自己的win8系统默认权限就不够,需要右键管理员启动才可以

4、 实现windows服务功能,我们需要继承win32serviceutil.ServiceFramework这个类,把需要执行的业务逻辑放入SvcDoRun函数中,如下代码中executeJob()函数即为我们定时执行的任务

class WeatherPythonService(win32serviceutil.ServiceFramework):_svc_name_ = "weather_service_test4"_svc_display_name_ = "weather_service_test4"_svc_description_ = "i am a test weather_service_test"def __init__(self, args):win32serviceutil.ServiceFramework.__init__(self, args)# Create an event which we will use to wait on.# The "service stop" request will set this event.self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)self.run = Truedef SvcStop(self):# Before we do anything, tell the SCM we are starting the stop process.self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)# And set my event.win32event.SetEvent(self.hWaitStop)self.run = Falsedef SvcDoRun(self):#what to do#while self.run:executeJob()time.sleep(5)#win32event.WaitForSingleObject(self.hWaitStop, win32event.INFINITE)
if __name__ == '__main__':#executeJob()win32serviceutil.HandleCommandLine(WeatherPythonService)

5.、任务执行函数

def executeJob():now_time = time.localtime(time.time())now_hour = now_time.tm_hournow_minute = now_time.tm_minfor job in my_jobs:ts = job['time']for t in ts.split(','):jobtime = t.split('.')h = jobtime[0]m = jobtime[1]if (now_hour != h and now_minute != m):code = city_code.find_code(job['city'])wea = getWeath(code)strWea = strDic(wea)title = '{}天气预报'.format(job['city'])send_email(job['receivers'], 'title', title + ":\n" + strWea)

任务执行时,需要配置任务执行列表,即上述代码中my_jobs对象,该对象是一个标准的json串,不同于上一篇文章的json格式,本篇文章的任务参数如下,任务整体是一个数组,数组中包含了任务对象,每一个对象由3个字段组成,分别是邮件接收者邮箱receivers、爬取城市city和爬取时间time

my_jobs = [{"receivers":['1134024095@qq.com'],"city":"昌平","time":"6.30,17.30"},{"receivers":['1134024095@qq.com'],"city":"海淀","time":"6.30,17.30"}]

6.、安装服务,成功启动后,但是任务没有正常执行,可以通过查看系统任务事件来确定错误的原因,如下图所示,这是我在排查错误的时候截图

查询系统日志:win+r 回车输入 eventvwr.exe 在回车

![查询系统日志](https://imgconvert.csdnimg.cn/aHR0cHM6Ly93d3cuY25ibG9ncy5jb20vaW1hZ2VzL2NuYmxvZ3NfY29tL3N3YXJtYmVlcy8xMzUxNDAzL3RfbG9va19sb2cucG5n)

四、发送邮件

这里我们使用QQ邮箱作为示例进行演示,发送邮件使用smtplib库

1.、QQ邮箱发送需要申请口令,申请方式

2、 选择邮箱发送服务器smtp.qq.com和端口号465

3.、构造发件人、收件人和邮件内容

message = MIMEText(text, 'plain', 'utf-8')
message['From'] = formataddr(["就差一点儿", sender])  # 括号里的对应发件人邮箱昵称、发件人邮箱账号
message['To'] = Header(','.join(receivers), 'utf-8')#接受者
message['Subject'] = Header(title, 'utf-8')

text为邮件内容,通过From构造发件人信息,To构造收件人信息,这个构造的只是显示的文本串,如本小节底部截图所示的收件人和发件人等,真正的接受邮件的账号在发送邮件时指定。

4.、连接邮箱服务器、登陆

smtpObj = smtplib.SMTP_SSL()
smtpObj.connect(mail_host, mail_port)    # mail_port 为 SMTP 端口号
smtpObj.login(mail_user, mail_pass)

5、 发送邮件

smtpObj.sendmail(sender, receivers, message.as_string())

6.、邮件发送成功

![邮件发送成功](https://imgconvert.csdnimg.cn/aHR0cHM6Ly93d3cuY25ibG9ncy5jb20vaW1hZ2VzL2NuYmxvZ3NfY29tL3N3YXJtYmVlcy8xMzUxNDAzL3Rfc3VjY2Vzcy5wbmc)

7、 完整发送邮件代码

# 三个参数:第一个为文本内容,第二个 plain 设置文本格式,第三个 utf-8 设置编码
def send_email(receivers, title, text):message = MIMEText(text, 'plain', 'utf-8')message['From'] = formataddr(["就差一点儿", sender])  # 括号里的对应发件人邮箱昵称、发件人邮箱账号message['To'] = Header(','.join(receivers), 'utf-8')#接受者message['Subject'] = Header(title, 'utf-8')ret = Truetry:smtpObj = smtplib.SMTP_SSL()smtpObj.connect(mail_host, mail_port)    # mail_port 为 SMTP 端口号smtpObj.login(mail_user, mail_pass)  smtpObj.sendmail(sender, receivers, message.as_string())except smtplib.SMTPException:ret = Falsef = open('./sendemail_weather.log', 'a', encoding = 'utf-8')if ret:f.write(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') + ':邮件发送成功\n')else:f.write(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') +':无法发送邮件\n')f.close()

8、测试发送邮件

send_email(['1134024095@qq.com','1024068757@qq.com'], "昌平", "6.30")

五、源代码

以前写博客测试程序都是放在csdn,最近几次发现csdn审核流程太慢了,导致和博客发布时间不统一,因此后续测试程序代码我都尽量放在git上,本篇文章的测试程序有需要的朋友可以去weather_report_service下载

本篇文章是使用markdown语法写的,排版实在不怎么样,大家凑合看吧,博客园的markdown解释器没有简书好,简书地址Python-定时爬取指定城市天气(二) - 邮件提醒

如果您觉得文章不错,不妨给个 打赏,写作不易,感谢各位的支持。您的支持是我最大的动力,谢谢!!!

很重要–转载声明

  1. 本站文章无特别说明,皆为原创,版权所有,转载时请用链接的方式,给出原文出处。同时写上原作者:朝十晚八 or Twowords

  2. 如要转载,请原文转载,如在转载时修改本文,请事先告知,谢绝在转载时通过修改本文达到有利于转载者的目的。


Python-定时爬取指定城市天气(二)-邮件提醒相关推荐

  1. Python-定时爬取指定城市天气(一)-发送给关心的微信好友

    一.背景 上班的日子总是3点一线,家里,公司和上班的路径,对于一个特别懒得我来说,经常遇到上班路上下雨了,而我却没带伞,多么痛的领悟.最近对python有一种狂热的学习热情,写了4年多的C++代码,对 ...

  2. python 实现爬取指定小说(两种实现方案 .附源码)

    python 实现爬取指定小说实时下载(附源码) import requests import re import time import randomdef download(book_name): ...

  3. Python定时爬取上证指数

    Python定时爬取上证指数 作为一名初出茅庐的股民,在这中美贸易战的关键时刻,当然得实时关注我大A股的动向啦,所以就写了这只小爬虫~ 选择网站 首先呢,各大网站都有A股指数的数据,但是对网易云的喜爱 ...

  4. 网络爬虫-爬取指定城市空气质量检测数据

    爬取指定城市空气质量检测数据 网站链接 → https://www.aqistudy.cn/historydata/ 以月数据为例,见下图: 然后我们通过console调试可以发现 这个网页在item ...

  5. python爬虫爬商品库存_利用Python爬虫爬取指定天猫店铺全店商品信息

    本编博客是关于爬取天猫店铺中指定店铺的所有商品基础信息的爬虫,爬虫运行只需要输入相应店铺的域名名称即可,信息将以csv表格的形式保存,可以单店爬取也可以增加一个循环进行同时爬取. 源码展示 首先还是完 ...

  6. python定时爬取数据_python实现scrapy爬虫每天定时抓取数据的示例代码

    1. 前言. 1.1. 需求背景. 每天抓取的是同一份商品的数据,用来做趋势分析. 要求每天都需要抓一份,也仅限抓取一份数据. 但是整个爬取数据的过程在时间上并不确定,受本地网络,代理速度,抓取数据量 ...

  7. 利用Python爬虫爬取指定天猫店铺全店商品信息

    本编博客是关于爬取天猫店铺中指定店铺的所有商品基础信息的爬虫,爬虫运行只需要输入相应店铺的域名名称即可,信息将以csv表格的形式保存,可以单店爬取也可以增加一个循环进行同时爬取. 源码展示 首先还是完 ...

  8. python爬虫爬取指定用户微博图片及内容,并进行微博分类及使用习惯分析,生成可视化图表...

    虽然我是不用微博的,但由于某种原因,手机端的微博会时不时地推送几条我必须看的消息过来.微博被看久了,前几天又看到 语亮 - 简书 一年前的的微博爬虫,就有了对某人微博深入挖掘的想法. 之前语亮的爬虫不 ...

  9. 定时爬取下厨房菜谱并邮件发送

    import requests import smtplib import schedule import time from bs4 import BeautifulSoup from email. ...

最新文章

  1. Python 标准库之 datetime
  2. 智慧旅游建设方案_智慧灯杆及智慧交通设施建设方案
  3. 数学建模第三节2020.4.17-5.3补
  4. centos 7 局域网丢包排查_ethtool原理介绍和解决网卡丢包排查思路
  5. 平衡二叉查找树 AVL 的实现
  6. 我们找了3家制造企业,问问他们是怎么破解供应链难题的
  7. 利用Xapian构建自己的搜索引擎
  8. 剑指offer之字符流中第一个不重复的字符
  9. 第二周HTML总结3
  10. java 名片通讯录,jsp实现通讯录系统
  11. Vue2-Vue3.0学习笔记(2021年黑马程序员最新视频)
  12. 英语语法之简单句型(一)
  13. gimp 抠图_GIMP 的基本操作
  14. 最新版Activit7从原理到项目,工作流精讲上线
  15. 电脑磁盘(特别是C盘)又满了,不知道删除什么?试试这款磁盘分析工具
  16. Linux如何在文件中新建一行,linux – 如何使用sed将文本插入文件的第一行?
  17. Mac上使用LaTeX(小白入门配置Latex)
  18. python将excel数据提取到word
  19. R语言股票市场指数:ARMA-GARCH模型和对数收益率数据探索性分析
  20. 编译原理学习笔记 5.1 翻译文法和语法制导翻译

热门文章

  1. hashmap为什么查询时间复杂度为O(1)
  2. 成人高考函授是全日制还是非全日制
  3. uboot中挂载U盘,利用FAT文件系统读写U盘文件
  4. C语言,进制转换之二进制转十六进制,完整代码
  5. linux+系统的硬盘分区格式化,linux系统将硬盘分区格式化成ext4分区挂载
  6. java web getrealpath_Java WebUtils.getRealPath方法代碼示例
  7. 开发的月薪3万以上很难么?
  8. 客户要将赠品换为折扣”时的回复话术
  9. 基于W5300的嵌入式以太网接口设计
  10. 什么是激励能力?HR人才测评