話說我是個火影迷,所以每到周三的時候,總會為了等火影的更新不停地刷新網頁。後來我還迷上了一部連載小說,每天不定期更新,於是每天就在那裡刷呀刷,F5都快爛了。F5爛了沒關系,程序猿那麼忙,怎麼可以把寶貴的時間浪費在這種地方 >_< 等到周四再去看火影不就行了麼,每隔一兩天看一次小說不就行了麼,可是,臣妾做不到啊 T.T
為了避免因為幾個連載而日夜煎熬,作為一個能拯救世界的技術宅,當然要做點什麼了 >_< 沒錯,讓機器來自動幫我檢測更新就行啦。所以,我只要寫一個程序,定時讀取連載目錄的內容,如果檢測到有更新,可以自動發一封郵件到我的QQ郵箱提醒我去看連載 Y^o^Y
首先是簡化我們的問題,上面提到的解決方案的程序裡面,可以分為以下幾個部分:
順便提一下,我最近做PHP比較多,所以開發語言就以 PHP 為主咯 ╮(╯_╰)╭
下面只對技術方案做簡單的說明,畢竟程序做的事情也很簡單,沒有什麼很神奇的代碼
前段時間剛好租過一台很矬的玩具級 Linux 服務器,所以我可以讓程序在這台服務器上24小時不停地跑。在 Linux 系統裡面,定時執行通常可以通過 crontab 命令新增一條定時任務。例如,我要設置每隔10分鐘執行一次,那麼 crontab 新增項的格式如下:
*/10 * * * * /path/task.sh
連載目錄是在一個網頁上的,要讀取出目錄的內容,還需要再把這個問題分解:
網頁的內容一般是是浏覽器作為客戶端通過 HTTP 協議從服務器獲取的。在我們的方案裡,我們要寫的程序就需要充當 HTTP 協議通信的客戶端來下載網頁的數據,熟悉 Linux 的你應該會想到 curl 命令行工具,這裡可以用 PHP 提供的 exec 函數來執行 curl 命令,或者使用 PHP 自帶的 curl 庫。
我使用的是 PHP 的 curl 庫,有興趣可以自行了解。
下載到的網頁文檔是 html 代碼,以我看的火影忍者為例,http://www.mangapanda.com/93/naruto.html ,(PS:表示看不懂日語而且英文版的更新速度比中文版的快,所以就...)
對於我們來說,連載目錄其實就是 html 文檔中的這部分 href 屬性值為 "/naruto/xxx" 的 <a> 元素了。
只要對下載到的 html 代碼用簡單的模式匹配做文本過濾,就可以得到連載目錄的內容了,我覺得你也應該想得到,用正則表達式來做這件事情再適合不過了。以剛才那個網頁為例,可以用下面這行正則表達式來粗略地過濾出連載目錄:
|href="/naruto/[^"]*"|
因為不同的要使用的正則表達式會不一樣,所以這個正則表達式應該是由用戶配置的。
在 PHP 裡面,可以使用 PHP PCRE Functions 中的 pregmatchall 函數。
這個相對比較簡單,只有有更新,那麼連載上當的內容就一定會有變化。所以只要把每次讀取到連載目錄和上一次讀取到的連載目錄的內容進行比較,只要有不同,就認定有有更新即可。
至於歷史數據的儲存,用一個文件就可以了。我有點小題大作地使用了 MySQL 數據庫來做這個事情。
不熟悉計算機網絡的我對郵件協議了解也是一塌糊塗,經過 google 之後,找到了 PHPMailer 庫,參考這個庫提供的 SMTP 的例子即可。
我使用一個 QQ 郵箱來作為發件人,需要注意的問題是這個 QQ 郵件要開通 SMTP 服務。
考慮到對用戶友好以及通用性,所以做了一個簡易的配置頁面,如下圖所示:
收到的提醒郵件的內容也很簡單,內容為空都可以,不過最好還是附上連載目錄的鏈接。
代碼可以使用 svn 檢出:
svn checkout "https://svn.code.sf.net/p/roxma-proj/code/php_learn"
這裡面夾雜著一些個人學習過程中積累的和主題無關的代碼,我相信應該不會有人想認真看,如果真的很想看,可以從 phplearn/apps/seriesupdate_remindder/check.php 跟進去。代碼真的不建議細看,我覺得最重要的內容其實還是“技術概要”那一節裡面的講到的思路,(好吧代碼太難看你偷偷告訴我就行了不要聲張)