Chinaunix首页 | 论坛 | 博客
  • 博客访问: 39994
  • 博文数量: 2
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 107
  • 用 户 组: 普通用户
  • 注册时间: 2012-11-07 07:21
文章分类

全部博文(2)

文章存档

2016年(1)

2014年(1)

我的朋友

分类: PERL

2014-02-25 21:47:47

       一直很喜欢CU论坛的Shell版块,但是似乎没有发现CU有手机客户端或者提醒工具之类的东西,这几天索性自己用python和perl做了一个简单的件提醒代码大概100多行,希望跟大家分享。
       说一下思路吧。以Shell版为例,我发现这个网页是静态的,也就是说直接抓取页面之后,分析一下关键字段,提取一些内容,就可以实现我说的功能。首先是当日的回帖数和发帖数,如果查看网页源代码,可以找到下面这行。

点击(此处)折叠或打开

  1. <span class="xs1 xw0 i">今日: <strong class="xi1">113</strong><span class="pipe">|</span>主题: <strong class="xi1">55427</strong>
         可以看到回帖数和总的帖数都有,再搜索一下发现"<span class="xs1 xw0 i">"这个关键字在整个网页源代码中只出现一次,也就是说,找到这一行,把里面的两个字段截取出来就可以了。因为我的设计是做成计划任务每分钟刷新一次网页,只要总帖数增加,就发邮件提醒,因此每次截取完两个字段之后,就保存到一个文件里面,然后对比总帖数只要增加就发送邮件。接下来是把当天的发帖抓出来。以下面这段代码为例。

点击(此处)折叠或打开

  1. <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>
  2. <a href="forum.php?mod=redirect&tid=4126289&goto=lastpost#lastpost" class="xi1">New</a>
  3. </th>
  4. <td class="by" style="border:1px solid #000;width:114px;text-align:center" bgcolor="#F0F3FA">
  5. <cite>
  6. <a href="space-uid-26152505.html" c="1">done_and_todo</a></cite>
  7. <em><span class="xi1">2014-02-25</span></em>
         以关键字"2014-02-25"搜索,往上5行是帖子的地址,6行是帖子的标题。只要把内容抓出来,稍加处理,就可以作为邮件的正文发送出去。
       接下来提一句,发送邮件本来在我自己的笔记本上直接用mail指令就可以做,考虑到自己的机器7*24小时运行负荷有点大,所以在linuxlearn.net上申请了一台虚拟主机,打算在上面跑,可惜它不提供mail指令,所以又用python做了个发送邮件的程序。
       最后顺带提一句,在crontab里面运行的程序,最好用绝对路径否则在读写文件或者调用程序时可能出错,这点开始不注意,调了好久才发现的。
       下面直接上代码。首先是用python抓去网页。

点击(此处)折叠或打开

  1. #! /usr/bin/python
  2. # -*- coding: UTF-8 -*-

  3. import urllib2

  4. try:
  5.     content=urllib2.urlopen('').read()
  6.     print content.decode('gbk').encode('utf-8')
  7.     # 编码按照utf8格式
  8. except Exception,errorcode:
  9.     print errorcode
       接下来是用python发送邮件。

点击(此处)折叠或打开

  1. #! /usr/bin/python
  2. # -*- coding: UTF-8 -*-

  3. import smtplib,sys
  4. from email.mime.text import MIMEText

  5. mailto_list="nathanielwen@163.com"
  6. # 设置目标邮箱列表
  7. mail_host="smtp.163.com"
  8. # 设置服务器
  9. mail_user="automail2wen"
  10. # 用户名
  11. mail_pass="!@#123"
  12. # 口令
  13. mail_postfix="163.com"
  14. # 发件箱的后缀
  15.   
  16. def send_mail(to_list,sub,content):
  17.     me="NoReply"+"<"+mail_user+"@"+mail_postfix+">"
  18.     msg = MIMEText(content,_subtype='html',_charset='utf8')
  19.     # 因为发送的是html格式,所以这里的subtype要对应,编码方式也要对于
  20.     msg['Subject'] = sub
  21.     msg['From'] = me
  22.     msg['To'] = to_list
  23.     try:
  24.         server = smtplib.SMTP()
  25.         server.connect(mail_host)
  26.         server.login(mail_user,mail_pass)
  27.         server.sendmail(me, to_list, msg.as_string())
  28.         server.close()
  29.         return True
  30.     except Exception, e:
  31.         print str(e)
  32.         return False

  33. if __name__ == '__main__':
  34.     subject="ChinaUnix论坛有更新"
  35.     content=sys.argv[1]
  36.     if send_mail(mailto_list,subject,content):
  37.         print "邮件发送成功"
  38.     else:
  39.         print "邮件发送失败"
       经过前面的铺垫,下面是用perl调用py抓网页,经过文本处理之后,再用py发送。

点击(此处)折叠或打开

  1. #! /usr/bin/perl

  2. $cwd='/home/nathanielwen/script/cu/';
  3. $fpath="$cwd"."/.file";

  4. chomp($now=`date '+%Y年%m月%d日 %H点%M分%S秒'`);
  5. # 获得当前系统时间,并去掉换行符

  6. open fh,"$fpath" || die "File open failed: $!\n";
  7. chomp(@lines=<fh>);
  8. close fh;
  9. # .file文件格式如下:
  10. # 第一行,时间
  11. # 第二行,今日回帖数
  12. # 第三行,总帖数

  13. die "cfg read error.\n" unless(defined $lines[0] and defined $lines[1] and defined $lines[2]);
  14. # 如果lines[0],lines[1]和lines[2]没有被赋值,说明读取.file文件时存在问题,终止程序

  15. @webpage=`$cwd/getwebpage.py`;
  16. # 运行python脚本将返回值保存在webpage中

  17. for (@webpage){
  18.     if(/<span class="xs1 xw0 i">/){
  19.      /.*>(\d+)<.*>(\d+)<.*/;
  20.      if($2>$lines[2]){
  21.      $lines[2]=$2;
  22.      $lines[1]=$1;
  23.             $sendflag=1;
  24.             #如果有更新,则开启标志位
  25.      }
  26.     }
  27. }

  28. chomp($mdate=`date +%Y-%m-%d`);
  29. $i=0;
  30. for (@webpage){
  31.     if(/$mdate<\/span>/ and $webpage[$i-6] =~ m/\A<em>/){
  32.         $webpage[$i-6] =~ m/ >(.+)<\/a>$z/;
  33.         $title=$1;
  34.         $webpage[$i-5] =~ m/"(.+?)"/;
  35.         $href=""."$1";
  36.         $content.="
    "
    ."".">> $title"."";
  37.     }
  38.     $i++;
  39. }

  40. $mailstatus="无需发送邮件";
  41. if($sendflag==1){
  42.     $sendflag=0;
  43.     $content =~ m/(.+)\Q$lines[3]/;
  44.     if(defined $1){
  45.         $mailstatus=`$cwd/sendmail.py "$1"`;
  46.     }else{
  47.         $mailstatus=`$cwd/sendmail.py "$content"`;
  48.     }
  49. }

  50. open fh,">$fpath" || die "File open failed: $!\n";
  51. # 准备将从网站抓回来的参数回写到.file文件中
  52. print fh "$now\n";
  53. print fh "$lines[1]\n";
  54. print fh "$lines[2]\n";
  55. print fh "$content\n";
  56. print fh "$mailstatus\n";
  57. close fh;
  58. # 回写,并关闭文件句柄
       里面的.file文件记录了每次运行程序的时间,当日回帖数,历史总帖数,当日发帖信息,邮件发送状态。程序能否正确运行跟.file文件有很大的关系。下面贴几张截图。
       这是手机端的邮件截图。绑定的是网易邮箱。如果有新帖子发出来的话会这样显示。


       下面上一张网页版本的。因为显示的是当日截止20:58所有的帖子,列表比较长,所以手机截图不方便。(只要把.file文件的第4行内容改成随意的字符串,就可以实现了

阅读(7058) | 评论(2) | 转发(3) |
0

上一篇:没有了

下一篇:python闭包浅析

给主人留下些什么吧!~~

nathanielwen2014-03-10 21:00:00

CU博客助理:嘉宾点评:第一次看到同时用python和perl写脚本的,对博主的语言掌握程度值得称赞.对于这个脚本有个疑问,放在cron中多久运行一次?如果运行过于频繁,是否会重复发送已读过的贴,如果间隔太大,是否会有遗漏?(感谢您参与“原创博文评选”获奖结果即将公布)

其实这个功能单独用python或者perl都可以实现,当初用这个组合有一部分原因是为了学习不同的脚本语言。另一方面是用perl处理文本实在是让人感觉太舒服了。我自己跑的时候cron是每分钟运行一次。用perl做了去重处理,不会出现重复现象。每分钟运行的话,也不会遗漏。谢谢您的点评。

回复 | 举报

CU博客助理2014-03-10 16:11:43

嘉宾点评:第一次看到同时用python和perl写脚本的,对博主的语言掌握程度值得称赞.对于这个脚本有个疑问,放在cron中多久运行一次?如果运行过于频繁,是否会重复发送已读过的贴,如果间隔太大,是否会有遗漏?(感谢您参与“原创博文评选”获奖结果即将公布)