寫在前面:
春節準備去北京玩耍,由於年前比較忙,今天才發現出行的日期裏面故宮門票已經售罄了。。。
在網上找了幾個旅行社都訂不到票,只有一家說可以幫忙搶票,但不保證能搶到。
我變想到結合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('[email protected]', '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('[email protected]', 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爬蟲和發送郵件的一次簡單嘗試,相信在以後的工作中會派上用場。