自动检查网页更新

需求:http://www.cnca.gov.cn/ywzl/gjgnhz/jkzl/这个网页会公布进口水产品境外生产企业注册名单,但公布日期不一定,所以想自动检查美国(2014年07月21日)这个条目是否更新了,如果更新了发邮件通知我。方法:获取网页,查看网页是否存在“美国(2014年07月21日)”若不存在则更新了。发邮件用PHPMailer的SMTP发送邮件很方便。

check.php

<?php
ignore_user_abort();//关掉浏览器,PHP脚本也可以继续执行.
set_time_limit(0);//通过set_time_limit(0)可以让程序无限制的执行下去
$interval=60*60*10;//单位是秒,每10小时执行一次
do{
	$run = include 'config.php';
	if(!$run) die('process abort');
	
	$url = "http://www.cnca.gov.cn/ywzl/gjgnhz/jkzl/"; 
	$ch = curl_init(); 
	curl_setopt ($ch, CURLOPT_URL, $url); 
	curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); 
	curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT,20); 
	$content = curl_exec($ch); 
	curl_close($ch); 
	$hasAutime=strpos($content,'美国(2014年07月21日'); 
	$hasAu=strpos($content,'美国');//防止没有下载到网页误触发,方法不可取
	
	 if (!$hasAutime && $hasAu){
	  require 'mail/mySendMail.php';
	  
	  $subject="内容有更新";
	  $body="内容有更新,请访问<a href='http://www.cnca.gov.cn/ywzl/gjgnhz/jkzl/'>http://www.cnca.gov.cn/ywzl/gjgnhz/jkzl/</a>";
	  if(mySendMail("receiver@qq.com","name",$subject,$body)){
				 echo "有更新,已发送邮件提醒";
		 } else {
				 echo "有更新,邮件发送失败";
		 }
		 die('process abort');
	 } else {
		 echo "not modified";
	 }
	
	sleep($interval);
}while(true);
?>

config.php是中止代码运行的,否则就永远执行下去了。将1改为0即可中止程序。

<?php
return 1;
?>

PHPMailer的配置很简单,我用过gmail和163邮箱都没问题,mySendMail.php

<?php
function mySendMail($recipient,$recipientName,$subject,$body){
require 'PHPMailerAutoload.php';

date_default_timezone_set("Asia/Shanghai");//设定时区东八区

$mail = new PHPMailer;
$mail->CharSet ="UTF-8";//设定邮件编码,默认ISO-8859-1,如果发中文此项必须设置,否则乱码

$mail->isSMTP();                 // Set mailer to use SMTP
$mail->Host = 'smtp.163.com';  // Specify main and backup server
$mail->Port = 465;                   // SMTP服务器的端口号
$mail->SMTPAuth = true;                               // Enable SMTP authentication
$mail->Username = 'my163acc';                            // SMTP username
$mail->Password = 'my163pw';                           // SMTP password
$mail->SMTPSecure = 'ssl';                            // Enable encryption, 'ssl' also accepted

$mail->From = 'my163acc@163.com';
$mail->FromName = 'no-reply';
$mail->addAddress($recipient, $recipientName);  // Add a recipient, Name is optional

$mail->WordWrap = 50;                                 // Set word wrap to 50 characters   
$mail->isHTML(true);                                  // Set email format to HTML

$mail->Subject = $subject;
$mail->Body    = $body;

if(!$mail->send()) {
   return false;
   exit;
}

return true;
}
?>

这个方法并不好,php周期执行任务比较危险。所以我后来使用了新浪的云服务SAE,用它的cron来定期执行检查就好多了。

用微博号登陆SAE,新建项目,我一看还支持python,就建了python的项目,结果SAE的python是2.7,我是按python3写的,就作罢了,不过还是贴一下python3的代码吧。

# encoding:UTF-8
import re,urllib.request,time,smtplib
from email.mime.text import MIMEText
from email.header import Header

def check():
  url = "http://www.cnca.gov.cn/ywzl/gjgnhz/jkzl/"
  request = urllib.request.Request(url)
  try:
    response = urllib.request.urlopen(request)
  except (urllib.error.HTTPError, socket.error,urllib.error.URLError) as e:
    print('Connection error occurred when inserting data.')
  else:
    r = response.read().decode('utf-8')
    patternAutime=re.compile("美国(2014年07月21日")
    matchAutime=patternAutime.search(r)
    patternAu=re.compile("美国")
    matchAu=patternAu.search(r)
    if (not matchAutime) and (matchAu):
      print("Modified!Modified!Modified!Modified!")
      sender = 'my163acc@163.com'
      receiver = 'receiver@qq.com'
      subject = '内容有更新'
      smtpserver = 'smtp.163.com'
      username = 'my163acc'
      password = 'pinwei4009988661'
      msg = MIMEText('内容有更新,请访问http://www.cnca.gov.cn/ywzl/gjgnhz/jkzl/','plain','utf-8')
      msg['Subject'] = Header(subject, 'utf-8')
      smtp = smtplib.SMTP()
      smtp.connect(smtpserver)
      smtp.login(username,password)
      smtp.sendmail(sender,receiver,msg.as_string())
      smtp.quit()
      return 0;
    else:
      print("no modify")
      return 1;
i=1
flag=1
while flag:#6000秒检查一次,最多查看20次
  st=check()
  time.sleep(6000)
  i+=1
  if (i>20) or (st==0):
    flag=0
exit()

然后新建了一个php项目,由于要上传PHPMailer的代码,所以在线编辑不够用,按文档安装了TortoiseSVN,不用不知道,真是比命令行方便啊!然后修改index.php

<?php
	$url = "http://www.cnca.gov.cn/ywzl/gjgnhz/jkzl/"; 
	$ch = curl_init(); 
	curl_setopt ($ch, CURLOPT_URL, $url); 
	curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); 
	curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT,20); 
	$content = curl_exec($ch); 
	curl_close($ch); 
	$hasAutime=strpos($content,'美国(2014年07月21日'); 
	$hasAu=strpos($content,'美国');
	
	 if (!$hasAutime && $hasAu){
	  require 'mail/mySendMail.php';
	  
	  $subject="内容有更新";
	  $body="内容有更新,请访问<a href='http://www.cnca.gov.cn/ywzl/gjgnhz/jkzl/'>http://www.cnca.gov.cn/ywzl/gjgnhz/jkzl/</a>";
	  if(mySendMail("receiver@qq.com","name",$subject,$body)){
				 echo "有更新,已发送邮件提醒";
		 } else {
				 echo "有更新,邮件发送失败";
		 }
		 echo "有更新,已发送邮件提醒";
	 } else {
		 echo "not modified";
	 }
?>

编辑config.yaml,cron字段设置每12小时执行一次

name: YOURPROJNAME
version: 1
cron:
    - description: cron check
      url: /index.php
      schedule: "* */12 * * *"
      timezone: Beijing

你的電子郵件位址並不會被公開。 必要欄位標記為 *