利用Linux虚拟主机打造自己的网络信息传送门
最近完成了一个日本公司的库存管理系统,开发费很准时的汇到了我的中行账户里。收日元是件很有成就感的事,那一堆零,看着就爽……不过这都是浮云啊,不换成人民钱怎么给我家包子买奶粉啊。最近日本受灾,日元汇率波动挺大,听某些专家讲,因为要筹集重建资金,日元总体还是要涨的。所以我给自己定了一个门槛,打算等汇率过了8.09才去兑换。可是要为了这个每天都要想着上网刷新中行的外汇牌价页面,感觉很麻烦,错失良机的可能性极大。所以就想做一个定时抓取网上汇率信息的web service,时时刻刻帮我盯着,一旦超过阙值,就用短信通知自己。感觉这个服务就象Portal–传送门,网上信息从一头儿扎进去,转啊转的,从另一头儿的个人短信端(email也行)就钻出来了。虽然我玩Portal游戏玩到头晕要吐,到第17关再也坚持不下去认输放弃了,但是自己做这个服务还是没什么问题的,花了周末一天时间搞定,也算是个实用的weekend project,记录下来给有类似需求的人做个参考。
事前准备
- 要获取的信息是互联网上公开的,信息展现页面格式基本固定无变化,以便机器按照一定的规律定时抓取;
- 有管理员权限的Linux虚拟主机服务,除了能够放PHP一类的活动页面程序外,最重要的是要有SSH登录,cron job和send mail功能;
- 如果要通过手机短信收取通知信息,需要有和自己的手机号码绑定的139.com信箱一个(联通电信应该也有类似的服务)。
制作过程
- 找到你要定时监视的网上信息源,记录下网址,然后看网页源代码,找到自己需要的部分,分析确定如何把这个数据准确地从其它信息中分离抓取出来。我就以中行外汇牌价页面信息为例说明:
我要抓的是日元现汇买入价,看上面的源代码可以发现,这个数字就在第一次出现日元两个字后面的第二行,去掉两头的<td bgcolor=”#FFFFFF”>和</td>以及一堆空格就行了; -
用SSH工具登录到自己的虚拟主机上,建立一个有执行权限的脚本文件scraper1.sh,代码如下:
##!/bin/sh dataSourceUrl="http://www.boc.cn/sourcedb/whpj/" dataProcessUrl="http://yourhosting.com/service1.php" exchangeRateFigure=$(wget -q -O- $dataSourceUrl --header 'Cache-control:no-cache' | iconv -f utf-8 -t gbk | sed -n '/日元/{n;s/
//;s/ //;s/ //g;p;}') exchangeRateDate=$(wget -q -O- $dataSourceUrl --header 'Cache-control:no-cache' | iconv -f utf-8 -t gbk | sed -n '/日元/{n;n;n;n;n;n;s///;s/ //;s/ //g;p;}') exchangeRateTime=$(wget -q -O- $dataSourceUrl --header 'Cache-control:no-cache' | iconv -f utf-8 -t gbk | sed -n '/日元/{n;n;n;n;n;n;n;s///;s///;s/ //;s/ //g;s/:/%3A/g;p;}') dataProcessUrl=$dataProcessUrl"?sid=1&dv1="$exchangeRateFigure"&dv2="$exchangeRateDate"&dv3="$exchangeRateTime wget -q -O- dataProcessUrl简要说明一下:第5行:首先是访问信息源网址获取网页,将网页从UTF-8编码转换为GBK编码,找到日元出现后的下一行信息,将
, 和所有空格信息去掉后,获得的数据存入变量中。
-
登录你的虚拟主机控制面板,在cron job中,按照你需要的定时间隔,执行上面的脚本,我的设定是:*/15 * * * * ~/public_html/prj/scraper1.sh,也就是每隔15分钟执行该路径下的scraper1.sh去抓取数据;
-
按照前面代码中建立的页面处理地址,在虚拟主机中建立相应的service1.php页面,同时建立一个有写入权限的service1.log文件,以便存储抓取来的数据。数据处理页面我用的是PHP,代码如下:
<?php $handle=fopen("service1.log","r"); $dataLine=fgets($handle); fclose($handle); $logData=explode(",", $dataLine); $alertThreshold=8.09;//触发短信通知的阙值 $exchangeRateFigure=$_GET['dv1']; $exchangeRateDate=$_GET['dv2']; $exchangeRateTime=$_GET['dv3']; if($logData[0]!=$exchangeRateFigure) { $handle=fopen('service1.log','w'); fwrite($handle,$exchangeRateFigure.','.$exchangeRateDate.','.$exchangeRateTime.','.$logData[3]); fclose($handle); if($exchangeRateFigure>=$alertThreshold && $exchangeRateDate!=$logData[3]){ $headers='From: aaa'.'rn'.'Reply-To: aaa@yourhosting.com'.'rn'.'X-Mailer: PHP/'.phpversion();//发件人和回复地址可以随便写 $to='13600000000@139.com';//你的139信箱地址 $subject='100 JPY now is '.$exchangeRateFigure.' CNY!'; $body='Date: '.$exchangeRateDate.', Time: '.$exchangeRateTime.', Figure: '.$exchangeRateFigure; mail($to, $subject, $body,$headers); $handle=fopen('service1.log','w'); fwrite($handle,$exchangeRateFigure.','.$exchangeRateDate.','.$exchangeRateTime.','.$exchangeRateDate); fclose($handle); } }
简要说明:这个页面的功能就是首先从service1.log文件中读取以往记录的数据,然后和新收到的数据比较,如果汇率数据不同,就将新信息和上一次短信通知日期的信息覆盖记录到service1.log文件中,下一步判断如果汇率达到阙值,且当天没有发送过短信通知,就给你手机绑定的139.com信箱地址发一封email,将汇率信息包含在信中,然后将新数据和当天日期覆盖记录到service1.log文件中;
-
用浏览器登录你的139.com信箱,开启邮件到达短信通知功能(只要不是彩信,其它几种形式都是免费的),这样就完成了!
最后还想说明的是:1)有send mail, ssh登录和cron job功能的Linux虚拟主机在国内不是每家都有,但是在国外算是基本配置,价格比国内还便宜(基本上是五、六美元到十几美元/月),绝对超值。2)这个传送门除了抓抓汇率信息,还可以有很多用处,我现在能想到的有:监视自己的交通一卡通余额,低于十元就通知赶紧充值;每天早上抓天气预报,有极端情况(雨雪降温酷热等)就通知一下;家庭安全监视……请大家集思广益吧!