写在前面:
春节准备去北京玩耍,由于年前比较忙,今天才发现出行的日期里面故宫门票已经售罄了。。。
在网上找了几个旅行社都订不到票,只有一家说可以帮忙抢票,但不保证能抢到。
我变想到结合python爬虫,爬去故宫网站信息,如果有余票,则发邮件给我,试试到底好不好用。当然,博主还是向旅行社预定了让他们帮忙抢,虽然最后可能都抢不到。
下面来看具体怎么实现的吧
逻辑描述:
使用到的python库主要如下:
urllib—爬去网页信息
zmail—发送邮件
故宫售票网站如下:
博主的出行日期为2月6日—2月8日,我们可以看到这段时间门票已经售罄了。
查看对应的网页源代码
于是,我只要通过判断,2月6日、2月7日、2月8日,是否是已售罄的状态,就可以判断是否有余票放出
<li class='closed'><b>2月6日</b>已售罄</li>
如果有余票放出,应该与2月12日的状态类似,如下:
<li onclick='v_home.fdate("2019-02-12","8","1","1",false,"1")'>
<b>
2月12日
</b>余61857人
</li>
起初,我想要只要网页里不存在
<li class='closed'><b>2月6日</b>已售罄</li>
<li class='closed'><b>2月7日</b>已售罄</li>
<li class='closed'><b>2月8日</b>已售罄</li>
这样的字符串,立即发邮件给我,但这样存在一个问题,随着日期向后推移,网页里的日期也是变化的。
例如,当时间到了2月7日,2月6日便不会出现在网页中,此时程序可能就会报错了
所以,我需要首先判断所要查询的日期在网页里是否存在,存在的情况下,再判断是否存在对应日期已售罄的字段。
如果不存在,则发送邮件。
下面看具体代码
实现代码:
# -*- coding: utf-8 -*-
"""
:author: Yihong Bao
:copyright: © 2019 Yihong Bao
"""
from urllib import request
import re
import time
import zmail
mail_content = {
'subject': '可以抢票了!',
'content_text': '可以抢票了!This message from zmail!'
}
# 使用你的邮件账户名和密码登录服务器
server = zmail.server('123@qq.com', '123456')
if server.smtp_able():
pass
if server.pop_able():
pass
def findLeft(day):
result0 = re.search(day, output)
if result0:
day = '<b>'+ day +'</b>'
result = re.search("(%s*)已售罄(%s*)" % (day, '</li>'), output, re.S)
if result:
print('No left')
pass
else:
print('mail')
server.send_mail('123@163.com', mail_content)
else:
print('No day')
pass
if __name__ == '__main__':
while True:
with request.urlopen('https://gugong.228.com.cn/') as html:
data = html.read()
output = data.decode('utf-8', 'ignore')
#print(output)
findLeft('2月6日')
findLeft('2月7日')
findLeft('2月8日')
findLeft('1月8日')
findLeft('2月12日')
time.sleep(5)
以上程序实现,每隔5秒去查询1月8日、2月6日、2月7日、2月8日、2月12日是否还有余票。
这里面需要注意的是,我使用的是zmail这个第三方库发送邮件,其中qq邮箱需要开启SMTP支持,密码为开启SMTP时设置的密码
程序验证:
我分别查询一个已经过去的日期1月8日,和有余票的日期2月12日,验证是否会收到邮件。
结果如下:
如果能够将程序放在公有云服务器上并能够访问互联网,我就可以通过这个程序监测我关心的日期是否有余票放出了。
总结:
虽然不知道这个小程序最终能否帮我进入故宫,最后可能确实是需要旅行社帮我抢的,但也算是python爬虫和发送邮件的一次简单尝试,相信在以后的工作中会派上用场。