最后一年的大学生活即将开始。回到宿舍打开电闸,就想起电量剩的不多了。为了避免突然断电的恐惧感,我一天里打开好几次华商e家(集成学校各方面服务的app)。索性编写一个爬虫,然后编写好了又想着怎么才能自动的提醒我……
···准备工作
1)明确目的:查询宿舍剩余电量,并尝试定时判断电量是否不足,需要提醒
2)使用fiddler获取app的请求信息
3)TextView查看对应文本位置
···编码部分
1)模拟http请求发送到服务器,返回html
2)使用正则表达式提取关键数据
3)提取关键数据
4) 将关键数据返回给提醒用户的代码中,进行判断是否需要提醒
下载并安装fiddler
https://www.telerik.com/fiddler
配置fiddler和手机wifi设置,使得fiddler可以顺利获取手机的网络请求
https://www.cnblogs.com/lizm166/p/8693085.html
这时候可以看到fidder出现新的请求,可以在右边看到如下图,找到关键位置代码
1)获取html,提取电量数据
引入模拟http请求所需的内置模块,以及正则表达式的模块
创建get_html(),按照之前的方法,开始请求html:
import re
import requests
def get_html():
url='http://pay.hsej.net/SignUp/Dormitory/EnergyRoomPay.aspx?data=22c8f65duY3VGh4Rwg8TyxexnQltb8nxxY7iM6W%2fHLZbm3ZwgMc%3d'
req = request.Request(url)
r = request.urlopen(req)
html = r.read()
html = str(html, encoding='UTF-8')
print(html)
发现输出的结果是:
请求异常,请稍后再试 #之后是包含js的空白页面代码
这里应该是需要模拟手机打开这个页面,了解到需要加入header请求,于是:
import re
import requests
def get_html():
url='http://pay.hsej.net/SignUp/Dormitory/EnergyRoomPay.aspx?data=22c8f65duY3VGh4Rwg8TyxexnQltb8nxxY7iM6W%2fHLZbm3ZwgMc%3d'
pattern = '([\s\S]*?)度'
headers = {
'Host': 'pay.hsej.net',
'Connection': 'keep-alive',
'User-Agent': 'Mozilla/5.0 (Linux; Android 7.1.2;XXXXXXXX',
#上面一部分代码用XX代替了,如果测试需要可以自行修改
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Referer': 'http://www.hsej.net/app/thirdparty/payorder?needLogin=1&target=http%3A%2F%2Fpay.hsej.net%2FSignUp%2FIndex&c=rRaDxC2Jdtc=&u=1Pj5IWQtkeg=&p=oTU7yIMCKx7mwWtrHagi/A==&ut=1&ct=56&token=QXaY9rWroKIMvazwf1OMAgMPphBvWsr%2Fy7IGAHLJeQgzsH1508Y85dIfbofhiWsyVr0ibHtF5qjk%0AzmHv3WsMBRKIJWJ2ldyCgYXo9iBqve%2F0EJBaOZ%2F7%2Bg%3D%3D',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,en-US;q=0.9',
'Cookie': 'ASP.NET_SessionId=dy3zvvtjztapzbybc11rdlbc',
'X-Requested-With': 'com.zhuochuang.hsej'
}
html = requests.get(url,headers = headers).text
html = re.findall(pattern, html)
print(html)
get_html()
得到list类型的数据:
['4.51']
2)判断,定时执行上面编写好的查询模块
找到一个定时执行的例子
https://blog.csdn.net/t8116189520/article/details/78832548
加入判断语句
# coding:utf8
# https://blog.csdn.net/t8116189520/article/details/78832548
import datetime
import time
import send_email
def doSth():
# 把爬虫程序放在这个类里
send_email.sendEmail()
print(u'这个程序要开始疯狂的运转啦')
# 一般网站都是1:00点更新数据,所以每天凌晨一点启动
def main(): # h=1, m=0
while True:
# now = datetime.datetime.now()
# # print(now.hour, now.minute)
# if now.hour == h and now.minute == m:
# break
# # 每隔60秒检测一次
time.sleep(30)
if send_email.power < 2.00:
print('电量不足')
doSth()
else:
print('电量充足')
main()
3)提醒方式
这里想到了几种提醒方式:
1. 发送短信
2. 微信公众号提醒
3. 发送邮件
由于暂时没有云服务器,也只是大一用过一两次,之后学习中再把脚本放在云服务器上(希望不是很久,毕竟要毕业了,没必要查电了。但是可以给师弟师妹们使用……)
找到发送邮件的例子,于是拿过来测试:
https://blog.csdn.net/sunhuaqiang1/article/details/70833199
# https://blog.csdn.net/sunhuaqiang1/article/details/70833199
import smtplib
from email.header import Header
from email.mime.text import MIMEText
import hsej_get_power
# 第三方 SMTP 服务
mail_host = "smtp.qq.com" # SMTP服务器
mail_user = "[email protected]" # 用户名
mail_pass = "XXXXXXXXXX" # 授权码,非登录密码
sender = '[email protected]' # 发件人邮箱(最好写全, 不然会失败)
receivers = '[email protected]' # 接收邮件,可设置为你的QQ邮箱或者其他邮箱
#复制过来的代码修改了下面这里
power = eval(hsej_get_power.get_html()[0]) # 转换成float类型
content = str(power)
title = '剩余电量' # 邮件主题
def sendEmail():
message = MIMEText(content, 'plain', 'utf-8') # 内容, 格式, 编码
message['From'] = "{}".format(sender)
message['To'] = ",".join(receivers)
message['Subject'] = title
try:
smtpObj = smtplib.SMTP_SSL(mail_host, 465) # 启用SSL发信, 端口一般是465
smtpObj.login(mail_user, mail_pass) # 登录验证
smtpObj.sendmail(sender, receivers, message.as_string()) # 发送
print("mail has been send successfully.")
except smtplib.SMTPException as e:
print(e)
# if __name__ == '__main__':
# sendEmail()
# receiver = '***'
# send_email2(mail_host, mail_user, mail_pass, receiver, title, content)
4)最终测试
运行2)步骤编写的自动运行代码,去掉判断语句,成功发送邮件
手机微信开通了邮件接收,顺利接收到电量数据
4.51……到底充还是不充呢,我也不开空调……
又一次在csdn博客发表自己不成熟的学习经验,才疏学浅,希望日后能有所作为