-
2009-10-10
飞信免费订阅宣讲会信息 - [工作相关]
1 发送短信的飞信命令
这个程序主要基于邓东东开发的 libfetion 库,这个库不是开源的,但是作者提供了头文件和库文件,所以我们可以使用它的 API 来写一些自己的程序。 本篇博客是基于Solrex Shuffling的"定制自己的免费天气预报短信".
发送信息的源程序以及库文件在Solrex的blog中有下载。需要的可以向我索要khb.hnu@gmail.com
不过发现 Solrex 的源程序sendsms.cpp文件有一个地方存在内存泄漏;strdup函数的返回值是一个新字符串,该串由malloc申请,所以必须要程序员手动去free掉这个空间;否则会导致内存泄漏;为什么会存在这么危险的函数存在呢?
- strdup
- The strdup()
function returns a pointer to a new string which is a duplicate of the
strings. Memory for the new string is obtained with malloc(3), and can
be freed with free(3).
strdup() conforms to SVr4, 4.3BSD, POSIX.1-2001.
同时,为了安全,我把飞信登录帐号和密码隐藏到源程序中。编译成可执行程序后是无法查看到的。
2 使用SHELL抓包
#!/bin/bash -x SMS_USER="15874082100,158xxxxxxxx,138xxxxxxx" URL="http://my.yingjiesheng.com/xuanjianghui_province_18.html" FILENAME="yjs-xjh.txt" get_html() { wget -nv -O $FILENAME $URL 2> /dev/null } parse_html() { #删除不必要的信息行 grep -v "查看" $FILENAME >temp grep -v "暂未开通" temp >$FILENAME grep -v "GA_googleFillSlot" $FILENAME >temp grep -v "加入手机提醒" temp >$FILENAME grep -v "最近更新" $FILENAME >temp mv temp $FILENAME #delete \n sed -nr -i ' H; $ { x; s/\n//g; p }' $FILENAME #每一天的记录从新行开始 sed -i -e 's$\(<img[^<]\+clock.gif" />\)$\n\1$g' $FILENAME #去除html中的标记符 sed -i -e 's/<[^<>]\+>//g' $FILENAME #删除html中的换行符  sed -i -e 's/ //g' $FILENAME #把每一条招聘记录从新行开始 sed -i -e 's/长沙\s/\n长沙/g' $FILENAME #为节省字符数,连续多个tab转换成单个tab sed -i -e 's/\t\+/\t/g' $FILENAME #为节省字符数,删除行首和行尾的多余空格 sed -i -e 's/\s\+$//g' $FILENAME sed -i -e 's/^\s\+//g' $FILENAME #由于第1行与最后一行不是我们所需要的信息,可以删除; sed -i -e '1d' $FILENAME sed -i -e '$d' $FILENAME #冗余信息 sed -i -e 's/长沙\t//g' $FILENAME #获取当前星期 week=`env LANG=en_US.UTF-8 date +%A` if [[ $week == "Saturday" ]] ; then maxday=7; else maxday=0; fi for((i=0;i<=30;i++)) do result=`grep -n ":$i 天" $FILENAME` if [[ $result != '' ]]; then if [ $i -gt $maxday ] ; then break; fi fi done #求取最后的行号 echo $result >temp endno=$((`awk -F: '{print $1}' temp`)) if [ $endno -gt 2 ];then #如果是星期天,则发送未来7天的宣讲会时间,并输出倒计时信息; #否则,只输出当天的宣讲会时间; if [[ $week == "Saturday" ]] ; then sed -i -e "1i\ 今天是 $week 未来一周的宣讲会安排如下:" $FILENAME sed -i -ne "1,$endno"p $FILENAME else sed -i -e "1a\ `date +%Y-%m-%d`($week)的宣讲会安排如下:" $FILENAME sed -i -ne "2,$endno"p $FILENAME fi else echo "今天没有宣讲会!" >$FILENAME fi } send_forcast() { #字符编码转换后通过飞信发送 iconv -f GB2312 -t UTF8 $FILENAME | sendsms -vl -t $SMS_USER } clear_html() { rm -f $FILENAME rm -f temp } get_html parse_html send_forcast #clear_html脚本里面注释很详细就不再唠叨。
上面的脚本虽然看起来简单,但是我还是花了一下午时间才把所需要的信息包从网页中抓取出来。碰到如下几个问题:
- sed命令对"中文字符串"的处理比较弱,很多在vim下可以完成的正则表达式替换工作使用sed就是无法完成;
- 字符编码导致乱码问题;GB2312,ISO-8859,UTF8之间转换;最后使用iconv解决;
3 自动定时运行
安装好 sendsms 到 /usr/bin 之后,将上面脚本放到 YOURPATH 下,然后在命令行执行:crontab -e,将下面一行添加进去:
00 09 * * * /YOURPATH/xjh.sh 1> /tmp/xjh.out 2> /tmp/xjh.err
这样每天上午9:00就会自动执行;4 后记
- 本打算把所有的程序扔到unix center上运行;后面发现unix center的ubuntu的主机是x84_64,所需要的libcurl需要自己重新编译安装,没权限; 所以只能用自己的机子跑。设置定时开机,处理完了后定时关机。
- 上面的脚本只是针对于特定的网页进行抓包;其他的应用需要重新修改脚本;
- 使用飞信主要是考虑到定时发送宣讲会信息到手机,便于身边没有电脑时查看;
- 使用脚本抓包目的是提取信息自动化,不用人工干预;
- 定时运行可以每天自动获取信息,以免因为忘记而错过一场宣讲会;
- 最大的优点是可以群发,实现信息共享,当然必须对方是我的飞信好友;
- 飞信本身还是有些问题,我碰到好几次段错误导致程序崩溃;