一直很喜欢逛CU论坛的Shell版块,但是似乎没有发现CU有手机客户端或者提醒工具之类的东西,这几天索性自己用python和perl做了一个简单的邮件提醒。代码大概100多行,希望跟大家分享。
说一下思路吧。以Shell版为例,我发现这个网页是静态的,也就是说直接抓取页面之后,分析一下关键字段,提取一些内容,就可以实现我说的功能。首先是当日的回帖数和发帖数,如果查看网页源代码,可以找到下面这行。
-
<span class="xs1 xw0 i">今日: <strong class="xi1">113</strong><span class="pipe">|</span>主题: <strong class="xi1">55427</strong>
可以看到回帖数和总的帖数都有,再搜索一下发现"<span class="xs1 xw0 i">"这个关键字在整个网页源代码中只出现一次,也就是说,找到这一行,把里面的两个字段截取出来就可以了。因为我的设计是做成计划任务每分钟刷新一次网页,只要总帖数增加,就发邮件提醒,因此每次截取完两个字段之后,就保存到一个文件里面,然后对比总帖数只要增加就发送邮件。接下来是把当天的发帖抓出来。以下面这段代码为例。
-
<em>[<a href="forum.php?mod=forumdisplay&fid=24&filter=typeid&typeid=506">文本处理</a>]</em> <a href="thread-4126289-1-1.html" onclick="atarget(this)" class="xst" >用vim将一列相同的数改成递加数</a>
-
<a href="forum.php?mod=redirect&tid=4126289&goto=lastpost#lastpost" class="xi1">New</a>
-
</th>
-
<td class="by" style="border:1px solid #000;width:114px;text-align:center" bgcolor="#F0F3FA">
-
<cite>
-
<a href="space-uid-26152505.html" c="1">done_and_todo</a></cite>
-
<em><span class="xi1">2014-02-25</span></em>
以关键字"2014-02-25"搜索,往上5行是帖子的地址,6行是帖子的标题。只要把内容抓出来,稍加处理,就可以作为邮件的正文发送出去。
接下来提一句,发送邮件本来在我自己的笔记本上直接用mail指令就可以做,考虑到自己的机器7*24小时运行负荷有点大,所以在linuxlearn.net上申请了一台虚拟主机,打算在上面跑,可惜它不提供mail指令,所以又用python做了个发送邮件的程序。
最后顺带提一句,在crontab里面运行的程序,最好用绝对路径否则在读写文件或者调用程序时可能出错,这点开始不注意,调了好久才发现的。
下面直接上代码。首先是用python抓去网页。
-
#! /usr/bin/python
-
# -*- coding: UTF-8 -*-
-
-
import urllib2
-
-
try:
-
content=urllib2.urlopen('').read()
-
print content.decode('gbk').encode('utf-8')
-
# 编码按照utf8格式
-
except Exception,errorcode:
-
print errorcode
接下来是用python发送邮件。
-
#! /usr/bin/python
-
# -*- coding: UTF-8 -*-
-
-
import smtplib,sys
-
from email.mime.text import MIMEText
-
-
mailto_list="nathanielwen@163.com"
-
# 设置目标邮箱列表
-
mail_host="smtp.163.com"
-
# 设置服务器
-
mail_user="automail2wen"
-
# 用户名
-
mail_pass="!@#123"
-
# 口令
-
mail_postfix="163.com"
-
# 发件箱的后缀
-
-
def send_mail(to_list,sub,content):
-
me="NoReply"+"<"+mail_user+"@"+mail_postfix+">"
-
msg = MIMEText(content,_subtype='html',_charset='utf8')
-
# 因为发送的是html格式,所以这里的subtype要对应,编码方式也要对于
-
msg['Subject'] = sub
-
msg['From'] = me
-
msg['To'] = to_list
-
try:
-
server = smtplib.SMTP()
-
server.connect(mail_host)
-
server.login(mail_user,mail_pass)
-
server.sendmail(me, to_list, msg.as_string())
-
server.close()
-
return True
-
except Exception, e:
-
print str(e)
-
return False
-
-
if __name__ == '__main__':
-
subject="ChinaUnix论坛有更新"
-
content=sys.argv[1]
-
if send_mail(mailto_list,subject,content):
-
print "邮件发送成功"
-
else:
-
print "邮件发送失败"
经过前面的铺垫,下面是用perl调用py抓网页,经过文本处理之后,再用py发送。
-
#! /usr/bin/perl
-
-
$cwd='/home/nathanielwen/script/cu/';
-
$fpath="$cwd"."/.file";
-
-
chomp($now=`date '+%Y年%m月%d日 %H点%M分%S秒'`);
-
# 获得当前系统时间,并去掉换行符
-
-
open fh,"$fpath" || die "File open failed: $!\n";
-
chomp(@lines=<fh>);
-
close fh;
-
# .file文件格式如下:
-
# 第一行,时间
-
# 第二行,今日回帖数
-
# 第三行,总帖数
-
-
die "cfg read error.\n" unless(defined $lines[0] and defined $lines[1] and defined $lines[2]);
-
# 如果lines[0],lines[1]和lines[2]没有被赋值,说明读取.file文件时存在问题,终止程序
-
-
@webpage=`$cwd/getwebpage.py`;
-
# 运行python脚本将返回值保存在webpage中
-
-
for (@webpage){
-
if(/<span class="xs1 xw0 i">/){
-
/.*>(\d+)<.*>(\d+)<.*/;
-
if($2>$lines[2]){
-
$lines[2]=$2;
-
$lines[1]=$1;
-
$sendflag=1;
-
#如果有更新,则开启标志位
-
}
-
}
-
}
-
-
chomp($mdate=`date +%Y-%m-%d`);
-
$i=0;
-
for (@webpage){
-
if(/$mdate<\/span>/ and $webpage[$i-6] =~ m/\A<em>/){
-
$webpage[$i-6] =~ m/ >(.+)<\/a>$z/;
-
$title=$1;
-
$webpage[$i-5] =~ m/"(.+?)"/;
-
$href=""."$1";
-
$content.="
"."".">> $title"."";
-
}
-
$i++;
-
}
-
-
$mailstatus="无需发送邮件";
-
if($sendflag==1){
-
$sendflag=0;
-
$content =~ m/(.+)\Q$lines[3]/;
-
if(defined $1){
-
$mailstatus=`$cwd/sendmail.py "$1"`;
-
}else{
-
$mailstatus=`$cwd/sendmail.py "$content"`;
-
}
-
}
-
-
open fh,">$fpath" || die "File open failed: $!\n";
-
# 准备将从网站抓回来的参数回写到.file文件中
-
print fh "$now\n";
-
print fh "$lines[1]\n";
-
print fh "$lines[2]\n";
-
print fh "$content\n";
-
print fh "$mailstatus\n";
-
close fh;
-
# 回写,并关闭文件句柄
里面的.file文件记录了每次运行程序的时间,当日回帖数,历史总帖数,当日发帖信息,邮件发送状态。程序能否正确运行跟.file文件有很大的关系。下面贴几张截图。
这是手机端的邮件截图。绑定的是网易邮箱。如果有新帖子发出来的话会这样显示。
下面上一张网页版本的。因为显示的是当日截止20:58所有的帖子,列表比较长,所以手机截图不方便。(只要把.file文件的第4行内容改成随意的字符串,就可以实现了)
阅读(1329) | 评论(1) | 转发(0) |