国庆节到了,一直也未能守在12306面前抢票,所以写了个脚本,调第三方的api挨个的查询有没有余票,有余票立马给我发短信或者微信通知。帖下代码。
#!/usr/bin/env php
<?php
function wlog($msg)
{
echo "[" . date("Y-m-d H:i:s", time()) . "]\t" . $msg . PHP_EOL;
}
class Play
{
public $i = 0;
/* 可配置项 开始 - --------------*/
public $time = 0.1 ; // 多少分钟执行一次
// https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
public $appid = "xxxxxxxxxxxxxxxx"; // 微信沙盒的appid
// 微信沙盒的appsecret
public $appsk = "xxxxxxxxxxxxxxxxxxxxxxx";
// 关注了测试号以后,再沙盒里面查找你需要通知的用户的appid,
// 能正确通知的前提是,在48小时内要与该测试号随便发一条消息就行了,
// 不然微信不让发通知。
public $openid
= [
"xxxxxxxxxxxxxxx",
];
// 短信通知列表 这是短信宝的短信通知,当然也可以用其他平台。
public $mobile
= [
"15800000000",
];
// 程序崩溃不通知名单列表
public $denyList
= [
"15811111111", // openid
];
// 需要查票的类型 . D动车,K快车,T特快,G高铁.
public $type = ["D", "K", "G"];
// 下面不用解释了吧,key, dtype不用变
public $config
= [
"start" => '成都',
'end' => '南昌',
'date' => '2017-10-01',
'dtype' => 'json',
'key' => 'c65caba9caeb60c4b1c192ca565af196',
];
// 如果不想用短信把这个true改成false
public $enableSms = true;
// 短信宝 账户
public $smsName = "";
// 短信宝 密码
public $smsPass = "";
/* 可配置项 end - --------------*/
/* 下面的不需要动了 */
public $accessToken = null;
public $expirs_in = 0;
public function __construct()
{
$this->run($this->time);
}
public function run($time)
{
if(extension_loaded('swoole'))
{
swoole_timer_tick(1000 * 60 * $time, [$this, 'find']);
}
else{
wlog("[警告] swoole 扩展不存在,请用crontab执行!");
wlog("crontab -e");
wlog("*/20 * * * * php /path/to/server.php");
wlog("service crond restart");
wlog("每20分钟执行一次");
$this->find();
}
}
public function find()
{
$this->i++;
try {
wlog("系统第" . $this->i . "次运行");
$url = "http://apis.juhe.cn/train/s2swithprice?" . http_build_query($this->config);
$content = json_decode(file_get_contents($url), true);
if (isset($content ['error_code']) && $content ['error_code'] != 0) {
// 请求失败, 需要通知我,
$this->msg("接口炸了");
$this->sendMsgToUser("接口炸了");
return;
}
$list = $content ['result']['list'];
foreach ($list as $value) {
if (in_array(strtoupper($value ['train_type']), $this->type)) // 动车是D 快车是L 高铁是G
{
wlog("有票::" . json_encode($value));
$this->msg("擦,有票了,赶紧买!!" . $value ['train_no']);
$this->sendMsgToUser("擦,有票了,赶紧买!!" . $value ['train_no']);
}
}
}
catch (\Exception $e) {
wlog('捕获了一个异常' . $e->getMessage() . "继续运行");
}
}
public function msg($content)
{
if(!$this->enableSms)
{
return ;
}
$name = $this->smsName;
$pass = md5($this->smsPass);
foreach ($this->mobile as $m) {
if(!in_array($m ,$this->denyList))
{
$u1 = sprintf("http://api.smsbao.com/sms?u=%s&p=%s&m=%s&c=%s", $name, $pass, $m, $content);
file_get_contents($u1);
}
}
}
function getAk()
{
if (time() < $this->expirs_in && $this->accessToken != null) {
return $this->accessToken;
}
$url = sprintf("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",
$this->appid,
$this->appsk
);
$res = json_decode(file_get_contents($url), true);
$this->expirs_in = time() + 7200;
return $this->accessToken = $res ['access_token'];
}
function sendMsgToUser($msg)
{
$ak = $this->getAk();
$url = sprintf("https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s", $ak);
foreach ($this->openid as $value) {
if(!in_array($value,$this->denyList)){
$data = [
"touser" => $value,
"msgtype" => "text",
"text" => [
"content" => $msg,
],
];
$data = json_encode($data, JSON_UNESCAPED_UNICODE);
$response = $this->post($url, $data); // 发完就行了。
$r = json_decode($response, true);
if ($r ['errcode'] != '0') {
wlog("微信推送失败::" . $response);
}
}
}
}
public function post($url, $data)
{
$curl = curl_init(); // 启动一个CURL会话
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)'); // 模拟用户使用的浏览器
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$tmpInfo = curl_exec($curl);
if (curl_errno($curl)) {
echo 'Errno' . curl_error($curl);
}
curl_close($curl);
return $tmpInfo;
}
}
$play = new Play();
前提得安装swoole拓展,如果没有安装swoole的话,则使用crontab执行就可以了。
*/20 * * * * php /path/to/server.php # 每20分钟执行一次。