系统网址是: http://pnpstock.sinaapp.com/
设计好系统后, 开始在新浪云平台 实施
代码库管理
新浪云用 svn 管理代码库
下载一个 小乌龟 svn, 就可以轻松提交代码
代码库 url 非常简单,就是 https://svn.sinaapp.com/yourapp/version
新浪云还提供本地开发测试环境 ( 就是个本地 WebServer ), 个人觉得没有必要用这个环境.现在网速足够快, 就直接提交运行就可以了.
如果你怕干扰正在运行系统, 建个子目录, 比如 test , 而后访问它就行了 ( 比如: http://pnpstock.sinaapp.com/test)
数据库管理
新浪云提供就是通用的mysqladmin, 直接在里面操作就行了
值得注意的是新浪云对数据库做了集群,想删除2000条记录都报错,这个时候只有走点弯路了,我的办法把记录转移到一个新表,删除旧表,再把新表改名为旧表
Crawl 股票信息
用新浪云提供SaeFetchurl 很容易抓取数据,代码如下
$f = new SaeFetchurl();
function craw_stock($codes) {
global $f;
// and sz sh prefix
$codes_backup = array_values($codes);
for( $i=0; $i < count($codes); $i++) {
$codes[$i] = "sz".$codes[$i];
$codes[$i] = preg_replace('/^sz6/','sh6',$codes[$i]);
}
$url = "http://hq.sinajs.cn/rn=6aqcc&list=".implode(",",$codes);
$rawinfo = $f->fetch($url);
if( preg_match_all( '/"(.*)"/',$rawinfo,$rawstocklist) )
print_r($rawstocklist);
else {
echo "NO FOUND";
exit();
}
}
而后数据经过parse 并转换为sql 语句,导入到mysql中
数据库接口
新浪云的数据接口很简单, 声明一下就可以使用了.
$mysql = new SaeMysql()
$mysql = new SaeMysql();
$sql = "select LPAD(code,6,'0') as code from code";
$records = $mysql->getData($sql);
$codes = array();
for( $i=0; $i< count($records); $i++ ) {
array_push ( $codes , $records[$i][code]);
if ( $i % 50 == 49 ) {
craw_stock($codes);
$codes = array();
}
}
不需要返回数据的可以调用 $mysql->runSql($sql);
这里有两点说明
1) code table 中数据哪里来,这是我从别处收集到直接写到库中的.以后要改进自动从网页收集资料更新.
2) 为了防止一次写如太多数据,我设定为每次插入50条,相当于限流
UI 实现
我使用了很成熟的Smarty http://www.smarty.net/先设定几个混搭smarty标记的HTML模板,而后在display 前填写数据.
下面是筛选结果显示的模板
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<head>
<LINK href="pystock.css" rel="stylesheet" type="text/css">
<script type="text/javascript">
setInterval('location.reload()', 60000);
</script>
<title>股市实时筛选</title>
</head>
<body>
<div id="wrapper">
<h1>
<{$filter_name}>
</h1>
<{include file="nav.tpl"}>
<!-- <{$sql}> -->
日期:
<{section name=cur loop=$records}>
<{if $smarty.section.cur.first}>
<{$records[cur].date}>
<{/if}>
<{/section}>
<table>
<tr>
<th>名称</th>
<th> 代码 </th>
<th> 价格 </th>
<th>新浪</th>
<!-- <th></th> -->
<th>自选</th>
</tr>
<{section name=cur loop=$records}>
<tr>
<td><{$records[cur].name}></td>
<td><{$records[cur].code}></td>
<td><{$records[cur].last_price}></td>
<!-- <td><a href='gd/single.php?code=<{$records[cur].code}>' target='_blank'>看图</a></td> -->
<td><a href='redirect.php?code=<{$records[cur].code}>' target='_blank'>看图</a></td>
<!-- <td><a href='addban.php?code=<{$records[cur].code}>' target='_blank'>封</a></td> -->
<td><a href='remind_add.php?filter=remind_stock&code=<{$records[cur].code}>' target='_blank'>加入</a></td>
<{sectionelse}>
<tr>当前无符合条件股票</tr>
<{/section}>
</table>
</div>
</body>
</html>
userCake 的集成
用户管理我搬用userCake http://usercake.com/
为了和我的系统集成做了一些工作
1)若干翻译
$lang = array_merge($lang,array(
"ACCOUNT_SPECIFY_USERNAME" => "请输入用户名",
"ACCOUNT_SPECIFY_PASSWORD" => "请输入密码",
"ACCOUNT_SPECIFY_EMAIL" => "请输入email",
"ACCOUNT_INVALID_EMAIL" => "email 不正确",
"ACCOUNT_INVALID_USERNAME" => "用户名不正确",
"ACCOUNT_USER_OR_EMAIL_INVALID" => "用户名或email不正确",
2)替换 userCake中的mysql 为SaeMysql
3) 替换userCake的邮件接口
编写个包装新浪云邮件api 的函数,给userCake 用
function sendMail($email,$title,$msg){
$mail = new SaeMail();
//$mail->setAttach( array("my_photo.jpg" => "");
$mail->quickSend(
$email,
$title ,
$msg ,
"yourname@qq.com" ,
"yourpassword" ,
"smtp.qq.com" ,
25
);
}
总之一边运行,一边改,看哪里有问题就去fix
计划任务
新浪云让用户创建一个config.yaml 文件, 在其中指定计划任务
因为股市上午和下午的开盘时间不同,所以要分段处理,处理稍微复杂些
本系统的文件如下:
---
name: pnpstock
version: 1
cron:
每周1到周5的 9:39 9:49 9:59
- description: crawl9
url: crawl.php
schedule: 39,49,59 9-10 * * 1-5
省略数据处理任务
每周1到周5的 11:9 11:19 11:29
- description: crawl11 url: crawl.php schedule: 9,19,29 11-12 * * 1-5
每周1到周5的 10-11点,1-3点,每10分钟执行
- description: crawl url: index_stock_crawl.php schedule: */10 10-11,1-3 * * 1-5
文字编码
最后只得一体的就是文字编码选择
我的网页是使用utf8,我抓取的网页可能不是utf8 编码,所以用iconv转换,再存储
$name = iconv("GBK", "UTF-8",$name);
$subsql = "select $code,'$name'";
array_push($subsqls,$subsql);
$sql = "replace into code (code,name) ". implode(" union ",$subsqls);
$mysql->runSql($sql);
而数据库表中 name 字段的设定与php 代码是一致的
CREATE TABLE IF NOT EXISTS `code` (
`code` decimal(6,0) NOT NULL,
`name` varchar(255) CHARACTER SET utf8 DEFAULT NULL,
PRIMARY KEY (`code`),
KEY `code` (`code`)
) ENGINE=MyISAM DEFAULT CHARSET=ascii;
基本说明完了,总之自己编写的php过渡到新浪云,还是比较平滑的.
新浪云可以免费申请的2000云豆, 基本可以完成系统的实验运行
此系统貌似简单,但还是陆续花费我不少业余功夫, 以后我还要不断这个系统,让它更加实用.