起因:想玩一下微信公众号,于是到新浪云搭了SAE。根据网上大牛们的博客,实现了根据消息被动回复功能,于是想进一步实现一些其他的功能,比如说每天定时从我们学校的网站爬取一些新闻存到数据库,然后根据用户的信息来推送。
解决思路:现在本地写好了爬虫脚本,没遇到什么大问题。于是决定将它放到新浪云上看能不能定时的跑起来。查看了新浪SAE的开发者文档,对于定时任务的概述,它是这样写的:
“定时任务服务可以用来定期触发您的应用执行一些后台任务,像定期清理和备份 MySQL 表中的数据、发送邮件通知等。定时任务的执行以 HTTP 方式触发,触发后真正执行的是您在应用中定义的 HTTP 回调函数。
任务执行的方式是 HTTP 调用(GET 方法),执行时间最长为 1800 秒 。
任务执行存在一定的时间误差,最大不超过 10 秒 。
任务不分应用版本,但只对默认版本生效,当切换代码默认版本时对应版本的定时任务会被激活。
任务的时间间隔粒度为分钟。
普通应用最大可以并发执行 12 个定时任务。多出的任务将不能被执行。”
对于配置定时任务的说明如下:
“您也可以在应用的配置文件 config.yaml 中添加任务。任务的执行状态可在定时任务的 Web 管理页面看到。
编辑 config.yaml 文件,增加 cron 段,例如:
cron:
- description: cron_test
url: /cron/make
schedule: "*/5 * * * *"
上面的示例添加了一个定时任务,该任务每 5 分钟调用 http:// 应用名.sinaapp.com/cron/make 一次。”
初次接触web.py,对于前端的认识也不是很全面,我暂且把“应用”理解为某一个页面下能执行某段任务的代码,于是为了搞清楚定时任务是如何工作的,我决定尝试一下在定时任务里清空数据库里的一张表。我是这样写的:
我新建了一个updateDaily.py,里面包含了一个UpdateDB类,用来清空数据库的某张表:
# -*- coding: utf-8 -*-
import os
from connectDB import connectMYSQL
import web
class updateDB:
def __init__(self):
self.query = connectMYSQL()
self.app_root = os.path.dirname(__file__)
self.templates_root = os.path.join(self.app_root, 'templates')
self.render = web.template.render(self.templates_root)
def GET(self):
sql = "truncate table board_data;"
self.query.execute(sql)
return "hello world"
其中connectDB是我写的一个连接Mysql数据库的模块,调用connectMySQL类下的execute函数可以直接执行sql语句,这个模块经测试可以成功返回查询语句的结果。
之后,我在index.wsgi中调用以上编写的模块,并且增加一个url,具体代码如下:
# -*- coding: utf-8 -*-
import os
import sae
import web
from connectToWechat import WechatInterface
from updateDaily import updateDB
urls = ('/weixin', 'WechatInterface', '/update', 'updateDB',)
app_root = os.path.dirname(__file__)
templates_root = os.path.join(app_root, 'templates')
render = web.template.render(templates_root)
app = web.application(urls, globals()).wsgifunc()
application = sae.create_wsgi_app(app)
如果我对于web.py模块的理解没错的话,当我定时任务调用“ http://应用名.applinzi.com/update”时,我数据库下的那张表就会被清空,并在网页上返回hello world。
最后,修改配置表config.yaml,增加以下代码:
cron:
- url: /update
schedule: "0 4 * * *"
description: "每天凌晨四点执行一次"
(实际上我在调试的时候是设置一分钟执行一次)
最后上传代码,可以看到新浪云SAE的定时任务页面已经有了我所配置的任务,但是每一次的执行结果都是返回404,然后数据库中的表并没有被清空。 定时任务的页面如下:
而定时任务的日志记录如下:
“[ 2016-11-07 04:00:16 ] status="404 Not Found" url="/update" response="not found" yq124”
检查了很多遍,调试了很多次,都没有发现问题在哪里,求各位大牛指点一下迷津啊。
提问:既然在定时任务的页面上可以看到我配置的定时任务,说明定时任务的配置是没问题的,再看到Index.wsgi里的URL,我只实现了两个功能,一个是在/weixin路径下实现微信公众号接口的token认真,这是没问题的,另外一个/update路径下实现的定时任务功能,但是触发这个页面的时候返回的是404,这让我百思不得其解,因为我在本地测试过,这种写法是可以返回"hello world"的,但是怎么到了新浪云上就失效了呢?跪求各位大牛指点迷津啊。