首先,我们选取“中国气象局 ·天气预报”网站作为爬虫爬取信息的目标网站。
中国气象局 ·天气预报网页链接:https://weather.cma.cn/
该网站没有robots协议,可以放心爬取。
我打开这个网站的时间为2021年7月30日,目前我所处的地点是江苏省南通市海门区,浏览器会根据目前你的ip地址自动定位到你所在的城市。
目标就是爬取当天的温度及天气状况,即下图中的"33℃/25℃"和"多云转阵雨"这两个数据。
检查该网页是动态网页还是静态网页。
检查方法:
如果preview里面呈现的内容和网页上看到的内容一致,那么就是静态网页;反之,则是动态网页。由上图可知,该网页为动态网页。
经过查找,我们发现所需的数据在XHR请求中,一层一层展开【data—daily—0—dayText/nightText/high/low】,便可得到我们所需的数据。
找到应访问的链接地址【https://weather.cma.cn/api/weather/view?stationid=】。
python代码实现。
需要requests模块,用来下载网页源代码。【非Python内置库,需pip install requests】
需要smtplib模块,用来连接服务器,发送邮件。【Python内置库】
需要email模块,用来自定义邮件内容。【Python内置库】
需要schedule模块,用来实现定时功能。【非Python内置模块,需pip install schedule】
需要time模块,用来检查部署情况时暂停。【Python内置模块】
将python程序部署到远端服务器。
QQ邮箱账号、QQ邮箱授权码、收件邮箱账号请自行填写!
import requests #调用requests模块。 import smtplib #调用smtplib模块。 from email.mime.text import MIMEText #从email模块下的mime模块下的text模块,导入MIMEText类。 from email.header import Header #从email模块下的header模块,导入Header类。 import schedule #调用schedule模块。 import time #调用time模块。 account='XXX@qq.com' #发件邮箱账号,自己填写。 password='XXX' #发件邮箱授权码,自己填写。 receiver='XXX' #收件邮箱账号,自己填写。 # 爬虫爬取天气信息函数spider()。 def spider(): url='https://weather.cma.cn/api/weather/view?stationid=' #所需数据的网页链接地址。 res=requests.get(url) #获取数据。 content=res.json() #使用json()方法将response对象转换为列表/字典。 Dict=content['data']['daily'][0] #一层一层地取字典/列表,获取今天的天气信息字典。 dayText=Dict['dayText'] #以dayText为键,查找今天白天的天气状况。 nightText=Dict['nightText'] #以nightText为键,查找今天夜里的天气状况。 high=Dict['high'] #以high为键,查找今天的最高气温。 low=Dict['low'] #以low为键,查找今天的最低气温。 # 不同的天气情况,返回不同的天气播报。 if dayText==nightText: res='主人,早上好!今天的天气状况为'+dayText+',最高温度:'+str(high)+'℃,最低温度:'+str(low)+'℃。' else: res='主人,早上好!今天的天气状况为'+dayText+'转'+nightText+',最高温度:'+str(high)+'℃,最低温度:'+str(low)+'℃。' return res # 发送邮件函数send_email()。 def send_email(t): emailhost='smtp.qq.com' #把qq邮箱的服务器地址赋值到变量emailhost上,地址应为字符串格式。 qqemail=smtplib.SMTP_SSL(emailhost) #实例化一个smtplib模块里的SMTP类的对象,这样就可以调用SMTP对象的方法和属性了。 qqemail.connect(emailhost,465) #连接服务器,第一个参数是服务器地址,第二个参数是SMTP_SSL端口号。 qqemail.login(account,password) #登录邮箱,第一个参数为邮箱账号,第二个参数为邮箱密码。 content=t #给邮件正文赋值,为字符串格式。 message=MIMEText(content,'plain','utf-8')#实例化一个MIMEText邮件对象,该对象需要写进三个参数,分别是邮件正文,文本格式【plain为纯文本】和编码。 subject='今日天气预报' #定义邮件主题,为字符串格式。 message['Subject']=Header(subject,'utf-8') #在等号的右边是实例化了一个Header邮件头对象,该对象需要写入两个参数,分别是邮件主题和编码,然后赋值给等号左边的变量message['Subject']。 qqemail.sendmail(account,receiver,message.as_string()) #发送邮件,调用sendmail()方法,写入三个参数,分别是发件人,收件人,和字符串格式的正文。 qqemail.quit() #退出邮箱。 # 定义job()函数。 def job(): print('开始一次任务!') t=spider() #将爬取到的天气信息赋值给变量t。 send_email(t) #发送邮件。 print('任务完成!') schedule.every().day.at('17:07').do(job) #部署在每天的06:00执行job()函数的任务。 # 检查部署的情况,如果任务准备就绪,就开始执行任务。【具体请见下方参考资料】 while True: schedule.run_pending() time.sleep(1)
服务器的购买及宝塔面板的安装此处省略。此处演示的服务器系统镜像为CentOs7.3。
桌面新建一个文件夹,将其命名为daily_weather。在里面新建一个.txt文件,把我们所需的python模块写入【requests、schedule】。将我们写好的天气预报.py程序拖入文件夹。【至于为什么要新建一个requirements.txt文件,请看step4的错误演示】
点击宝塔面板左侧的软件商店,在应用搜索栏里面搜索Python,安装Python项目管理器。
点击Python项目管理器右侧的设置按钮,选择版本管理,安装Python项目所需的Python版本。
点击宝塔面板左侧文件选项,进入根目录下的www文件夹。
注:文件夹放哪个目录都可,这边演示选择将daily_weather这一文件夹放入根目录下的www文件夹下。
点击上传—上传目录—选中daily_weather文件夹—上传。【此处daily_weather文件夹里面,我故意去掉requirements.txt文件,来给大家演示没有requirements.txt文件,接下来会发生什么】注:此时的daily_weather文件里面就一个天气预报.py文件。
上传后,www目录下多了一个daily_weather文件夹。
点击左侧的软件商店—点击上方"已安装"—点击Python项目管理器右侧的设置—项目管理—添加项目
填写以下信息—确定
目前,我们有两种解决方法,a.把刚才的requirements.txt文件上传到www目录下的daily_weather文件夹;b.取消勾选安装模块依赖。这边采取b方法作为演示。
注:采用a方法的话,上传操作完成后,添加Python项目—选择安装模块依赖—点击确定后,即完成项目的创建。无需再安装模块,Python项目管理器会根据requirements.txt文件里面列出的所需模块名,帮你自动安装好这些模块。
b方法(傻瓜式操作):
点击项目管理中刚添加的项目右侧的"模块"—输入模块名称requests—添加—输入模块名称schedule—添加。
点击已暂停—确定,开启项目。
效果图:
验证部署是否成功,执笔于此的时间为18:48
进入www目录—daily_weather文件夹—天气预报.py,修改Python程序的定时为19:10,看看待会我的163邮箱能都收到天气预报提醒!【注:天气预报.py程序中收件人邮箱,我填的是163邮箱】
注:每次修改完定时时间,要重新启动一下项目。没重新启动项目会导致等会邮箱收不到天气预报!具体缘由有待考究!
静待19:10的到来!