現學現用:追女朋友必不可少的Python技能!
編者有言:多喝熱水太敷衍,日常堅持不斷的噓寒問暖反而顯得溫馨。程式設計師怎麼用自己最擅長的事追到女神?本文將給你一些實用建議。
一、背景
上班的日子總是3點一線——家裡,公司和上班的路徑,對於我這樣一個特別懶的人來說,經常遇到上班路上下雨了,而我卻沒帶傘,多麼痛的領悟。
最近對Python有一種狂熱的學習熱情,寫了4年多的C++程式碼,對於Python我不能說簡單,但是它做東西確實太快了,現有的第三方資源真的炒雞多,用的我也是不亦樂乎。
除了上班忘記帶傘,每天重複性的工作還有很多,比如上下班打卡、每個禮拜的週報,還有如果有關心的女神,也可以做定時傳送心裡話,或者定時提醒等各種服務。
有時候我就會想,如果有一個人能按時提醒我就好了,不過這種想法也就停留了那麼幾分鐘,然後就被自己pass掉了,因為別人也可能忘記啊……
那麼這件事是不是可以交給程式來做呢?畢竟程式可是會老老實實的做重複性的工作,而且樂此不疲。
上述問題的場景大多都是需要程式在指定時間、或者指定場合提醒我們該幹什麼了,本篇文章就定時天氣提醒服務來做開篇,講述使用Python怎麼完成這樣一個任務,既然這樣,那我們就開始構思我們的程式吧。
為了幫助小夥伴們更好的學習Python,小編整理了Python的相關學習視訊及學習路線圖,新增小編學習群943752371即可獲取
二、構思
看過背景中的需求描述,要實現這個功能,我們需要解決以下這麼幾個問題:
1、爬取天氣資訊
2、動態獲取指定城市天氣
3、傳送天氣資訊給指定微信好友
4、定時觸發爬取動作
5、怎麼關聯微信賬號
下面我們將一步一步解決上述幾個問題,並實現我們的需求。
三、爬取天氣資訊
我們解決問題的順序不是簡單的按照12345這樣,而是會按照思考的順序來。
首先來解決問題1:
對於使用過爬蟲的同學來說,爬取天氣資訊並不難,之前也瞭解過一些爬取web資訊的程式碼,簡單的爬蟲無非就是那麼幾步:
確定爬取的url,使用瀏覽器開啟
F12檢視網頁佈局資訊
使用xpath或者bs4進行節點定位
拿到頁面資訊
自己拼接爬取到的資訊
寫檔案、寫資料庫、傳送網路等等
這裡貼下我之前寫的幾個簡單爬蟲:
Python-爬取校花網視訊(單執行緒和多執行緒版本)
https://www.cnblogs.com/swarmbees/p/10017073.html
Python-爬取妹子圖(單執行緒和多執行緒版本)
https://www.cnblogs.com/swarmbees/p/10016919.html
Python爬蟲Scrapy(一)-我爬了boss資料
https://www.cnblogs.com/swarmbees/p/10011898.html
下面是爬取城市天氣的python方法,需要注意一點的是getWeath介面的引數city_code,這是一個全國城市編碼,每個城市都是唯一的,這個表格我已經整理成了一個txt文件,後續放原始碼的時候會一併提供。
上述方法可以獲取一個城市的天氣資訊,並儲存在一個字典中,我們要傳送給好友,還需要對其進行字串處理,處理程式碼如下:
全國城市編碼如下圖所示,每個城市的編碼都是一個9位的數字組成,獲取天氣資訊時是通過指定該編碼進行查詢。
四、傳送給指定好友
解決問題3:傳送訊息給好友。
解決問題5:怎麼關聯微信賬號,使用wechat_sender庫。
我們自己爬取到的天氣資訊怎麼和微信能扯上關係呢?
可以看看我以前提到的《微信聊天機器人-儲存好友分享訊息》,簡單來說就是登陸一個web版本的微信賬號,在我們的電腦上,做這麼一個機器人使用了庫wxpy,要想和這個機器人勾搭上,那我們就需要請出我們今天的重磅嘉賓wechat_sender。
《微信聊天機器人-儲存好友分享訊息》
https://www.cnblogs.com/swarmbees/p/9996547.html
wxpy
https://wxpy.readthedocs.io/zh/latest/index.html
https://github.com/youfou/wxpy
wechat_sender是基於wxpy和tornado實現的一個可以將你的網站、爬蟲、指令碼等其他應用中各種訊息(日誌、報警、執行結果等)傳送到微信的工具包,有了它,我們的訊息就可以順利的傳送到我們的微信賬戶了。
wechat_sender
https://wechat-sender.readthedocs.io/zh_CN/latest/index.html
tornado
https://github.com/tornadoweb/tornado
互動流程
如上圖所示,首先使用wxpy登陸微信機器人,當然這個機器人使用的是我們自己的微信賬號。
這裡需要特別注意一點,《微信聊天機器人-儲存好友分享訊息》中講述的機器人進入命令狀態是使用的embed()方法,在這裡我們不能使用該介面了,我們需要換成上述互動流程的很關鍵的一步,使用listen介面進行監聽,這樣我們的web工具才能傳送訊息給機器人,建議仔細閱讀一遍wechat_sender說明文件,內容不多。
登陸微信機器人
爬取到天氣資訊以後,使用wechat_sender中的Sender類直接傳送訊息給微信機器人,下屬程式碼中嘗試是用了多種傳送訊息的方式,程式碼中都有詳細註釋,可自行閱讀。
登陸微信機器人,下邊程式碼中第12行非常關鍵,這一行就是用來監聽外部程式傳送訊息的。
五、城市編碼
解決問題2:根據配置的城市名稱動態獲取城市編碼,然後請求資料。
由於沒有介面可以直接獲取城市編碼,因此這裡我們自己封裝了一個類來進行管理城市名稱和城市編碼,拉取城市天氣時,只要輸入城市名稱,那麼城市編碼即可通過該類獲取到,具體程式碼如下:
六、定時任務
解決問題4:定時傳送任務
我們的需求是每日定時拉取天氣資訊,併發送給指定好友,Python有一個APScheduler庫,支援定時任務,具體使用比較複雜,我也沒有仔細研究。這裡我們只是需要使用一個定時任務,其他不做介紹,有興趣的同學可自行研究。
在研究定時任務的過程中,一直沒有找到BackgroundScheduler類add_job時,回撥函式怎麼傳遞引數,因此這裡我封裝了一個類,讓定時任務和任務回撥處於一個域內,這樣引數就可以放在類的成員變數未知,不需要傳遞了,哪位大神如果會操作,可以評論區指出,非常感謝。
後期出現不同型別任務時,我們就需要再封裝新的類。
上述MyJob類有2個介面,一個是任務排程器回撥介面,不需要我們呼叫,另一個是載入任務介面,這個任務引數是一個標準的json串,由任務觸發時間和具體的任務列表組成,任務觸發時間主要是給排程器使用,任務列表就是排程器觸發時的回撥函式需要執行的任務數量。
如上述任務json串來說,我們的任務id為my_jobs,在每天的6:30和17:30,我們需要執行items列表所指出的任務,任務列表是一個列表,列表中儲存的是具體任務,receivers代表任務執行完畢需要傳送的好友,city是爬取的天氣名稱,測試效果如下圖所示:
由於任務排程器不是一個阻塞性的程式,如果我們不在主執行緒進行阻塞程式,那麼程式就會直接退出;如果阻塞了主執行緒,那麼任務排程程式也將會被阻塞。
因此這裡在新增任務排程後,我們開啟了一個子執行緒,主要就是為了不讓主執行緒退出,這樣做其實不合理,但是我們這裡僅僅是為了演示,對這些問題的進一步處理我們之後會有文章來詳細分析。
喜歡的同學可以自己嘗試完成下這個小程式,或者選擇一個類似的場景進行處理,本篇文章中還有幾個需要優化的地方,由於篇幅問題,我們之後再進行講解:
1、定時任務做成windows服務,這樣更優雅,隨開機啟動
2、傳送訊息給微信好友換成傳送郵件給指定郵箱