Python-定时爬取指定城市天气(一)-发送给关心的微信好友
一、背景
上班的日子总是3点一线,家里,公司和上班的路径,对于一个特别懒得我来说,经常遇到上班路上下雨了,而我却没带伞,多么痛的领悟。最近对python有一种狂热的学习热情,写了4年多的C++代码,对于python我不能说简单,但是他做东西确实太快了,现有的第三方资源真的炒鸡多,用的我也是不亦乐乎。除了上班忘记带伞,每天重复性的工作还有很多,比如上下班打卡、每个礼拜的周报,还有如果有关心的女神,也可以做定时发送心里话,或者定时提醒等各种服务。有时候想如果有一个人能按时提醒我就好了,这种想法也就停留了那么几分钟就被自己pass掉了,因为别人也可能忘记啊。。。那么这件事是不是可以交给程序来做呢!毕竟程序可是会老老实实的做重复性的工作,而且他们乐此不疲。
上述问题的场景大多都是需要程序在指定时间、或者指定场合提醒我们该干什么了,本篇文章就定时天气提醒服务来做开篇,讲述使用Python怎么完成这样一个任务,既然这样,那我们就开始构思我们的程序吧
二、构思
看过背景中的需求描述,要实现这个功能,我们需要解决以下这么几个问题:
1、爬取天气信息,那么接下来就产生第二个问题了
2、动态获取指定城市天气
3、发送天气信息给指定微信好友
4、定时触发爬取动作
5、怎么关联微信账号
下面我们将一步一步解决上述几个问题,并实现我们的需求
三、爬取天气
解决问题1:
对于使用过爬虫的同学来说,爬取天气信息并不难,之前也了解过一些爬取web信息的代码,简单的爬虫无非就是那么几步
1、确定爬取的url,使用浏览器打开
2、F12查看网页布局信息
3、使用xpath或者bs4进行节点定位
4、拿到页面信息
5、自己拼接爬取到的信息
6、写文件、写数据库、发送网络等等
这里贴下我之前写的几个简单爬虫:
1、Python-爬取校花网视频(单线程和多线程版本)
2、Python-爬取妹子图(单线程和多线程版本)
3、python爬虫Scrapy(一)-我爬了boss数据,这个应该还有个下篇,后面待续
下面是爬取城市天气的python方法,需要注意一点的是getWeath接口的参数city_code,这是一个全国城市编码,每个城市都是唯一的,这个表格我已经整理成了一个txt文档,后续放源码的时候会一并提供。
1 headers ={2 "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36",3 }4 5 defgetWeath(city_code):6 try:7 url = f'http://www.weather.com.cn/weather/{city_code}.shtml' 8 resp = requests.get(url, headers =headers)9 exceptBaseException as e:10 print(e)11 return{}12 13 resp.encoding = 'utf-8' 14 soup = BeautifulSoup(resp.text, 'html.parser')15 tagToday = soup.find('p', class_ = "tem") #第一个包含class="tem"的p标签即为存放今天天气数据的标签 16 try:17 temperatureHigh = tagToday.span.string #有时候这个最高温度是不显示的,此时利用第二天的最高温度代替。 18 exceptAttributeError:19 temperatureHigh = tagToday.find_next('p', class_="tem").span.string #获取第二天的最高温度代替 20 21 temperatureLow = tagToday.i.string #获取最低温度 22 weather = soup.find('p', class_ = "wea").string #获取天气 23 wind = soup.find('p', class_ = "win") #获取风力 24 clothes = soup.find('li', class_ = "li3 hot") #穿衣指数 25 26 return {'温度':f'{temperatureHigh}/{temperatureLow}' 27 , '天气':weather28 , '风力':wind.i.string29 , '穿衣':clothes.a.span.string + ',' + clothes.a.p.string}
上述方法可以获取一个城市的天气信息,并储存在一个字典中,我们要发送给好友,还需要对其进行字符串处理,处理代码如下:
1 defstrDic(dic):2 str_weather = '' 3 for key indic:4 str_weather += key + ':' +dic[key]5 str_weather += '\n' 6 return str_weather
全国城市编码如下图所示,每个城市的编码都是一个9位的数字组成,获取天气信息时是通过指定该编码进行查询。
四、发送给指定好友
解决问题3:发送消息给好友
解决问题5:怎么关联微信账号,使用wechat_sender库
我们自己爬取到的天气信息怎么和微信能扯上关系呢,这个时候就要提到我之前写过的一篇文章微信聊天机器人-存储好友分享消息,没有看过的同学可以快速浏览一遍,简单来说就是登陆一个web版本的微信账号,在我们的电脑上,做这么一个机器人使用了库wxpy,要想和这个机器人勾搭上,那我们就需要请出我们今天的重磅嘉宾wechat_sender,wechat_sender是基于wxpy和tornado 实现的一个可以将你的网站,爬虫,脚本等其他应用中各种消息(日志,报警,运行结果等)发送到微信的工具包,有了他我们的消息就可以顺利的发送到我们的饿微信账户了。
交互流程
如上图所示,首先使用wxpy登陆微信机器人,当然这个机器人使用的是我们自己的微信账号,这里需要特别注意一点,微信聊天机器人-存储好友分享消息这篇文章中讲述的机器人进入命令状态是使用的embed()方法,在这里我们不能使用该接口了,我们需要换成上述交互流程的很关键的一步,使用listen接口进行监听,这样我们的web工具才能发送消息给机器人,建议仔细阅读一遍wechat_sender说明文档,内容不多
登陆微信机器人
爬取到天气信息以后,使用wechat_sender中的Sender类直接发送消息给微信机器人,下属代码中尝试是用来多种发送消息的方式,代码中都有详细注释,可自行阅读
1 defsendWeatherMsg(receivers, msg):2 try:3 #receivers = [u'拉卡拉', u'证明给他看', u'李静'] 4 5 #receivers = u'李静,情绕指尖' 6 7 ''' 8 #发送给指定好友 如果好友不存在 则发送给文件夹传输助手9 Sender(receivers = u'证明给他看').send(msg)10 Sender(receivers = u'拉卡拉').send(msg)11 Sender(receivers = u'李静').send(msg)12 ''' 13 14 ''' ''' 15 #发送给指定接收的用户 16 #receivers = u'拉卡拉' 17 #接受者必须是监听对象的子集 18 sender = Sender(receivers = receivers, token = 'weather_report_123456789')19 sender.send(msg)#如果没有指定receivers则发送给文件传输助手 20 21 22 ''' 23 receivers = u'李静,情绕指尖'24 sender = Sender(receivers = receivers, token = 'weather_report_123456789')25 26 #有时候好使 有时候不好使27 sender.send_to('@wss', u'拉卡拉') #消息发送失败 会默认发送给receivers的第一个用户 Sender和Listen28 #sender.send_to(msg, u'证明给他看')29 ''' 30 31 #测试控制命令 32 ''' 33 receivers = u'拉卡拉'34 sender = Sender(receivers = receivers, token = 'weather_report_123456789')35 sender.send('@wss')#文如果没有指定receivers则发送给文件传输助手件传输助手36 ''' 37 38 exceptBaseException as e:39 print(e)
登陆微信机器人微信聊天机器人-存储好友分享消息已经讲过,有不懂的同学可以回头看下,下边代码中第12行非常关键,这一行就是用来监听外部程序发送消息的。
1 bot = Bot(cache_path =True)2 3 receivers =[]4 receivers.append(bot.file_helper)5 receivers.append(bot.friends().search('拉卡拉')[0])6 receivers.append(ensure_one(bot.friends().search('李静', city='西安')))#有可能搜索出多个结果 7 receivers.append(bot.friends().search('证明给他看')[0])8 receivers.append(bot.friends().search('妈')[0])9 10 print(receivers)11 12 listen(bot, receivers = receivers, token = 'weather_report_123456789') #关键一步
五、城市编码
解决问题2,根据配置的城市名称动态获取城市编码,然后请求数据
由于没有接口可以直接获取城市编码,因此这里我们自己封装了一个类来进行管理城市名称和城市编码,拉取城市天气时,只要输入城市名称,那么城市编码即可通过该类获取到,具体代码如下
1 importos2 3 classCity(object):4 def __init__(self):5 self.city ={}6 7 defload(self, file):8 ifos.path.exists(file):9 with open(file, 'r', encoding = 'utf-8') as f:10 cityInfo = f.readline().strip('\n')11 whilecityInfo:12 datas = cityInfo.split(':')13 self.city[datas[0]] = datas[1]14 cityInfo = f.readline().strip('\n')15 16 deffind_code(self, city_name):#根据城市名称,查找城市吧编码17 if city_name inself.city:18 returnself.city[city_name]19 return ''
六、定时任务
解决问题4:定时发送任务
我们的需求是每日定时拉取天气信息,并发送给指定好友,python有一个APScheduler库,支持定时任务,具体使用比较负责,我也没有仔细研究,这里我们只是需要使用一个定时任务,其他不做介绍,有兴趣的同学可自行研究。
在研究定时任务的过程中,一直没有找到BackgroundScheduler类add_job时,回调函数怎么传递参数,因此这里我封装了一个类,让定时任务和任务回调处于一个域内,这样参数就可以放在类的成员变量未知,不需要传递了,哪位大神如果会次操作,可以评论区指出,非常感谢
1 classMyJob(object):2 def __sendWeatherMsg(self):3 for my_job inself.my_jobs:4 code = city_code.find_code(my_job['city'])5 wea =getWeath(code)6 strWea =strDic(wea)7 title = '{}天气预报:\n'.format(my_job['city'])8 sendWeatherMsg(my_job['receivers'], title + strWea)#发送天气信息给文件助手 9 10 defaddMyJobs(self, json_job):11 self.my_jobs = json_job['items']12 scheduler =BackgroundScheduler()13 scheduler.add_job(self.__sendWeatherMsg, trigger = 'cron', hour = json_job['hour']14 , minute = json_job['minute'], second = '5,10,15,20,25,30,35,40,45,50,55')15 scheduler.start()
后期出现不同类型任务时,我们就需要在封装新的类。上述MyJob类有2个接口,一个是任务调度器回调接口,不需要我们调用,另一个是加载任务接口,这个任务参数是一个标准的json串,由任务触发时间和具体的任务列表组成,任务触发时间主要是给调度器使用,任务列表就是调度器触发时的回调函数需要执行的任务数量。
1 my_jobs ={2 "id":"my_jobs",3 "hour":"6, 17",4 "minute":"30",5 "items":[{6 "receivers":"文件传输助手,李静,拉卡拉",7 "city":"昌平" 8 },{9 "receivers":"文件传输助手,李静,拉卡拉",10 "city":"海淀" 11 }]12 }
如上述任务json串来说,我们的任务id为my_jobs,在每天的6.30和17.30,我们需要执行items列表所指出的任务,任务列表是一个列表,列表中存储的是具体任务,receivers代表任务执行完毕需要发送的好友,city是爬取的天气名称,测试效果如下图所示
由于任务调度器不是一个阻塞性的程序,如果我们不在主线程进行阻塞程序,那么程序就会直接退出,如果阻塞了主线程,那么任务调度程序也将会被阻塞,因此这里在添加任务调度后,我们开启了一个子线程,主要就是为了不让主线程退出,这样做其实不合理,但是我们这里仅仅是为了演示,在下篇文章中这些问题我们在做进一步处理。
1 city_code =city_code.City()2 city_code.load('city_code.txt')3 4 if __name__ == "__main__":5 try:6 ''' ''' 7 my_job =MyJob()8 my_job.addMyJobs(test_jobs)9 10 f = lambda x : lambda y : x+y11 t = Timer.Timer(f, 24 * 60 * 60)#创建线程 一天给自己发一条消息 12 t.setDaemon(True)13 t.start()14 t.join() #防止主主线程退出15 16 #SendWeatherMsg(my_msg) 17 18 exceptResponseError as e:19 print(e.err_code, e.err_msg) #查看错误号和错误消息
喜欢的同学可以自己尝试完成下这个小程序,或者选择一个类似的场景进行处理,本篇文章中还有几个需要优化的地方,由于篇幅问题,我们在下篇中进行讲解
1、定时任务做成windows服务,这样更优雅,随开机启动
2、发送消息给微信好友换成发送邮件给指定邮箱
七、资源下载
需要全部代码的到csdn直接下载:Python-定时爬取指定城市天气(一)-发送给关心的微信好友
转载声明:本站文章无特别说明,皆为原创,版权所有,转载请注明:朝十晚八
转载于:https://www.cnblogs.com/swarmbees/p/10023491.html
Python-定时爬取指定城市天气(一)-发送给关心的微信好友相关推荐
- Python-定时爬取指定城市天气(二)-邮件提醒
文章目录 一.概述 二.模块重新划分 三.优化定时任务 四.发送邮件 五.源代码 一.概述 上一篇文章python-定时爬取指定城市天气(一)-发送给关心的微信好友中我们讲述了怎么定时爬取城市天气,并 ...
- Python定时爬取上证指数
Python定时爬取上证指数 作为一名初出茅庐的股民,在这中美贸易战的关键时刻,当然得实时关注我大A股的动向啦,所以就写了这只小爬虫~ 选择网站 首先呢,各大网站都有A股指数的数据,但是对网易云的喜爱 ...
- python 实现爬取指定小说(两种实现方案 .附源码)
python 实现爬取指定小说实时下载(附源码) import requests import re import time import randomdef download(book_name): ...
- 网络爬虫-爬取指定城市空气质量检测数据
爬取指定城市空气质量检测数据 网站链接 → https://www.aqistudy.cn/historydata/ 以月数据为例,见下图: 然后我们通过console调试可以发现 这个网页在item ...
- 【爬虫】每天定时爬取网页小故事并发送至指定邮箱
看题目 ,需要实现三部分工作,第一部分为爬取网页小故事,第二部分为发送至指定邮箱,第三部分为定时启动程序.爬取网页内容可以使用BeautifulSoup库实现,发送邮件可以使用smtplib库实现,定 ...
- python爬虫爬商品库存_利用Python爬虫爬取指定天猫店铺全店商品信息
本编博客是关于爬取天猫店铺中指定店铺的所有商品基础信息的爬虫,爬虫运行只需要输入相应店铺的域名名称即可,信息将以csv表格的形式保存,可以单店爬取也可以增加一个循环进行同时爬取. 源码展示 首先还是完 ...
- python定时爬取数据_python实现scrapy爬虫每天定时抓取数据的示例代码
1. 前言. 1.1. 需求背景. 每天抓取的是同一份商品的数据,用来做趋势分析. 要求每天都需要抓一份,也仅限抓取一份数据. 但是整个爬取数据的过程在时间上并不确定,受本地网络,代理速度,抓取数据量 ...
- 利用Python爬虫爬取指定天猫店铺全店商品信息
本编博客是关于爬取天猫店铺中指定店铺的所有商品基础信息的爬虫,爬虫运行只需要输入相应店铺的域名名称即可,信息将以csv表格的形式保存,可以单店爬取也可以增加一个循环进行同时爬取. 源码展示 首先还是完 ...
- python爬虫爬取指定用户微博图片及内容,并进行微博分类及使用习惯分析,生成可视化图表...
虽然我是不用微博的,但由于某种原因,手机端的微博会时不时地推送几条我必须看的消息过来.微博被看久了,前几天又看到 语亮 - 简书 一年前的的微博爬虫,就有了对某人微博深入挖掘的想法. 之前语亮的爬虫不 ...
最新文章
- 使用 EasyPOI 优雅导出Excel模板数据(含图片)
- jquery键盘事件全记录
- Linux 相关发音
- android studio 虚拟机adb.exe已停止工作的处理
- 斑能不能彻底去掉_海鲜不能和什么一起吃
- halcon识别ocr汉字_手写汉字识别——手写文本快速电子化的好方法
- firefox驱动_零适配 + 全兼容!龙芯电脑推出办公外设利旧通用解决方案:运行原生 Windows 驱动程序...
- 监听在微信中打开页面时的自带返回按钮事件
- ​比较一下主流国际快递系统 国际快递公司如何选择
- c盘瘦身(c盘瘦身最简单的方法win10)
- android ConstraintLayout布局 详解
- 腾讯Tendis 号称能干掉 Redis ?你继续吹牛吧 !
- html如何调图片透明度,改变图片的透明度.html
- 武汉大学计算机2019转专业,武汉大学可以转专业吗,武汉大学新生转专业政策
- Win10环境下初始化MySQL
- enum ordinal java_Spring 3.x自动将枚举的ordinal值转换为枚举类型
- vue中好用的视频插件推荐,video+canvas实现视频截图第一帧,ffmpeg实现视频截图第一帧
- c语言str系列函数
- android wifi优化,WiFi信号如何快速优化? 安卓APP来帮忙
- iOS常用功能 - 根据链接生成二维码图片
热门文章
- 基于k-means聚类算法对NBA球员数据的一次聚类分析
- 告别“浮云” 享用云计算服务优势
- 数据库底层原理-------数据结构
- 中国计算机网络设备制造业总体趋势免费版,致自己的心灵鸡汤说说,句句经典,引人深思!...
- 《那些年啊,那些事——一个程序员的奋斗史》——94
- [案例2-5]石头 剪刀 布小游戏
- POI 自定义16进制颜色导出
- Powerbuilder混淆与加密器(powerbuilder防止反编译,pb混淆器,支持5-12) obfuscator for PowerBuilder...
- AM5728调试经历
- 微信小程序视频URL测试地址 MP4格式