在这篇教程中,我们将介绍如何在微信公众平台上开发天气预报功能。我们将使用中国天气网的气象数据接口来获取天气信息。

这篇教程将介绍以下内容:

  1. 获取中国天气网的气象数据
  2. 在微信公众平台中回复天气

一、中国天气网

中国天气网提供了丰富的气象数据接口。下面我们介绍主要的几个:

国家根节点接口:

http://flash.weather.com.cn/wmaps/xml/china.xml

该接口以XML格式列出所有的省(自治区、直辖市)的中文名称(quName)和拼音名称(pyName)及省会城市的天气信息,其中广东的数据如下:

<city quName="广东" pyName="guangdong" cityname="广州" state1="2" state2="7" stateDetailed="阴转小雨" tem1="8" tem2="15" windState="微风"/>

该接口的主要功能是通过它获取省级节点的拼音名称。以广东为例:其pyName是“Guangdong”。

省级节点接口(以广东为例):

http://flash.weather.com.cn/wmaps/xml/Guangdong.xml

该接口以XML格式列出当前省下辖所有市的中文名称(quName)、拼音名称(pyName)、中心坐标、天气信息以及城市编码。其中深圳的数据如下所示:

<city cityX="409" cityY="257" cityname="深圳" centername="深圳" fontColor="FFFFFF" pyName="shenzhen" state1="1" state2="1" stateDetailed="多云" tem1="12" tem2="18" temNow="12" windState="微风" windDir="东北风" windPower="1级" humidity="74%" time="21:15" url="101280601"/>

在这个接口中主要获取城市名称及相应的城市编码。例如,深圳的城市编码为:101280601。可以编写程序将全国城市拓扑结构采集下来。也可以使用方倍工作室已经采集好的,点击这里下载。

实时天气数据(以深圳为例):

http://www.weather.com.cn/data/sk/101280601.html

该接口以JSON格式列出当前城市的实时天气状况。如下所示:

{"weatherinfo": {"city": "深圳","cityid": "101280601","temp": "12","WD": "东北风","WS": "1级","SD": "75%","WSE": "1","time": "21:20","isRadar": "1","Radar": "JC_RADAR_AZ9755_JB"}
}

实时天气数据参数说明下所示:

六日天气数据(以深圳为例):

http://m.weather.com.cn/data/101280601.html

该接口以JSON格式列出当前城市的六日天气状况。如下所示:

{"weatherinfo": {"city": "深圳","city_en": "shenzhen","date_y": "2014年2月15日","date": "","week": "星期六","fchh": "18","cityid": "101280601","temp1": "12℃~18℃","temp2": "16℃~21℃","temp3": "17℃~23℃","temp4": "11℃~18℃","temp5": "10℃~15℃","temp6": "12℃~17℃","tempF1": "53.6℉~64.4℉","tempF2": "60.8℉~69.8℉","tempF3": "62.6℉~73.4℉","tempF4": "51.8℉~64.4℉","tempF5": "50℉~59℉","tempF6": "53.6℉~62.6℉","weather1": "多云","weather2": "阴","weather3": "多云","weather4": "中雨","weather5": "多云","weather6": "阴","img1": "1","img2": "99","img3": "2","img4": "99","img5": "1","img6": "99","img7": "8","img8": "99","img9": "1","img10": "99","img11": "2","img12": "99","img_single": "1","img_title1": "多云","img_title2": "多云","img_title3": "阴","img_title4": "阴","img_title5": "多云","img_title6": "多云","img_title7": "中雨","img_title8": "中雨","img_title9": "多云","img_title10": "多云","img_title11": "阴","img_title12": "阴","img_title_single": "多云","wind1": "微风","wind2": "微风","wind3": "微风","wind4": "东北风3-4级","wind5": "微风","wind6": "微风","fx1": "微风","fx2": "微风","fl1": "小于3级","fl2": "小于3级","fl3": "小于3级","fl4": "3-4级","fl5": "小于3级","fl6": "小于3级","index": "较舒适","index_d": "建议着薄外套、开衫牛仔衫裤等服装。年老体弱者应适当添加衣物,宜着夹克衫、薄毛衣等。","index48": "较舒适","index48_d": "建议着薄外套、开衫牛仔衫裤等服装。年老体弱者应适当添加衣物,宜着夹克衫、薄毛衣等。","index_uv": "最弱","index48_uv": "最弱","index_xc": "适宜","index_tr": "适宜","index_co": "舒适","st1": "19","st2": "13","st3": "23","st4": "16","st5": "24","st6": "18","index_cl": "适宜","index_ls": "适宜","index_ag": "不易发"}
}

未来六日天气数据主要参数说明如下表所示:

以上接口是我们做天气预报功能将使用到的接口。

二、微信公众平台开发

1. 需要将城市编码对照表导入到数据库中,以下是SAE导入后截图

2. 将城市名转为城市代码的方法,这将在用户发送城市名的时候调用

 1 function fromNameToCode($name)
 2 {
 3     $mysql_host = SAE_MYSQL_HOST_M;
 4     $mysql_host_s = SAE_MYSQL_HOST_S;
 5     $mysql_port = SAE_MYSQL_PORT;
 6     $mysql_user = SAE_MYSQL_USER;
 7     $mysql_password = SAE_MYSQL_PASS;
 8     $mysql_database = SAE_MYSQL_DB;
 9
10     $mysql_table = "weather";
11     $mysql_state = "SELECT * FROM ".$mysql_table." WHERE `cityName` = '".$name."'";
12
13     $con = mysql_connect($mysql_host.':'.$mysql_port, $mysql_user, $mysql_password, true);
14     if (!$con){
15         die('Could not connect: ' . mysql_error());
16     }
17     mysql_query("SET NAMES 'UTF8'");
18     mysql_select_db($mysql_database, $con);
19     $result = mysql_query($mysql_state);
20     $cityCode = "";
21     while($row = mysql_fetch_array($result))
22     {
23         $cityCode = $row['cityCode'];
24         break;
25     }
26     mysql_close($con);
27     return $cityCode;
28 }

3. 编写接口调用函数,用于向天气网发送cURL请求,获取数据

 1 function httpRequest($url)
 2 {
 3     $ch = curl_init();
 4     curl_setopt($ch, CURLOPT_URL, $url);
 5     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 6     $output = curl_exec($ch);
 7     curl_close($ch);
 8     if ($output === FALSE){
 9         return "cURL Error: ". curl_error($ch);
10     }
11     return $output;
12 }

4. 编写获取天气数据的函数,这里获取实时天气和未来3日天气,并将返回结果封装成图文信息的数组

 1 function getWeatherInfo($cityName)
 2 {
 3     $cityCode = fromNameToCode($cityName);
 4
 5     if ($cityCode == "")
 6     {
 7         return "错误的城市名或者此城市不在数据库中!";
 8     }
 9
10     //获取实时天气
11     $url = "http://www.weather.com.cn/data/sk/".$cityCode.".html";
12     $output = httpRequest($url);
13     $weather = json_decode($output, true);
14     $info = $weather['weatherinfo'];
15
16     $weatherArray = array();
17     $weatherArray[] = array("Title"=>$info['city']."天气预报", "Description"=>"", "PicUrl"=>"", "Url" =>"");
18     if ((int)$cityCode < 101340000){
19         $result = "实况 温度:".$info['temp']."℃ 湿度:".$info['SD']." 风速:".$info['WD'].$info['WSE']."级";
20         $weatherArray[] = array("Title"=>str_replace("%", "﹪", $result), "Description"=>"", "PicUrl"=>"", "Url" =>"");
21     }
22
23     //获取六日天气
24     $url = "http://m.weather.com.cn/data/".$cityCode.".html";
25     $output = httpRequest($url);
26     $weather = json_decode($output, true);
27     $info = $weather['weatherinfo'];
28
29     if (!empty($info['index_d'])){
30         $weatherArray[] = array("Title" =>$info['index_d'], "Description" =>"", "PicUrl" =>"", "Url" =>"");
31     }
32
33     $weekArray = array("日","一","二","三","四","五","六");
34     $maxlength = 3;
35     for ($i = 1; $i <= $maxlength; $i++) {
36         $offset = strtotime("+".($i-1)." day");
37         $subTitle = date("m月d日",$offset)." 周".$weekArray[date('w',$offset)]." ".$info['temp'.$i]." ".$info['weather'.$i]." ".$info['wind'.$i];
38         $weatherArray[] = array("Title" =>$subTitle, "Description" =>"", "PicUrl" =>"http://discuz.comli.com/weixin/weather/"."d".sprintf("%02u",$info['img'.(($i *2)-1)]).".jpg", "Url" =>"");
39     }
40
41     return $weatherArray;
42 }

5. 在微信公众平台接口函数中处理收到的文本消息时,文本将为城市名,直接调用获取天气的函数

  1 /*
  2     方倍工作室
  3     CopyRight 2013 All Rights Reserved
  4 */
  5
  6 define("TOKEN", "weixin");
  7
  8 $wechatObj = new wechatCallbackapiTest();
  9 if (!isset($_GET['echostr'])) {
 10     $wechatObj->responseMsg();
 11 }else{
 12     $wechatObj->valid();
 13 }
 14
 15 class wechatCallbackapiTest
 16 {
 17     public function valid()
 18     {
 19         $echoStr = $_GET["echostr"];
 20         if($this->checkSignature()){
 21             echo $echoStr;
 22             exit;
 23         }
 24     }
 25
 26     private function checkSignature()
 27     {
 28         $signature = $_GET["signature"];
 29         $timestamp = $_GET["timestamp"];
 30         $nonce = $_GET["nonce"];
 31         $token = TOKEN;
 32         $tmpArr = array($token, $timestamp, $nonce);
 33         sort($tmpArr);
 34         $tmpStr = implode($tmpArr);
 35         $tmpStr = sha1($tmpStr);
 36
 37         if($tmpStr == $signature){
 38             return true;
 39         }else{
 40             return false;
 41         }
 42     }
 43
 44     public function responseMsg()
 45     {
 46         $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
 47         if (!empty($postStr)){
 48             $this->logger("R ".$postStr);
 49             $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
 50             $RX_TYPE = trim($postObj->MsgType);
 51
 52             switch ($RX_TYPE)
 53             {
 54                 case "event":
 55                     $result = $this->receiveEvent($postObj);
 56                     break;
 57                 case "text":
 58                     $result = $this->receiveText($postObj);
 59                     break;
 60             }
 61             $this->logger("T ".$result);
 62             echo $result;
 63         }else {
 64             echo "";
 65             exit;
 66         }
 67     }
 68
 69     private function receiveEvent($object)
 70     {
 71         $content = "";
 72         switch ($object->Event)
 73         {
 74             case "subscribe":
 75                 $content = "欢迎关注方倍工作室 ";
 76                 break;
 77             case "unsubscribe":
 78                 $content = "取消关注";
 79                 break;
 80         }
 81         $result = $this->transmitText($object, $content);
 82         return $result;
 83     }
 84
 85     private function receiveText($object)
 86     {
 87         $keyword = trim($object->Content);
 88
 89         include("weather.php");
 90         $content = getWeatherInfo($keyword);
 91         $result = $this->transmitNews($object, $content);
 92         return $result;
 93     }
 94
 95
 96     private function transmitText($object, $content)
 97     {
 98         $textTpl = "<xml>
 99 <ToUserName><![CDATA[%s]]></ToUserName>
100 <FromUserName><![CDATA[%s]]></FromUserName>
101 <CreateTime>%s</CreateTime>
102 <MsgType><![CDATA[text]]></MsgType>
103 <Content><![CDATA[%s]]></Content>
104 </xml>";
105         $result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(), $content);
106         return $result;
107     }
108
109     private function transmitNews($object, $arr_item)
110     {
111         if(!is_array($arr_item))
112             return;
113
114         $itemTpl = "    <item>
115         <Title><![CDATA[%s]]></Title>
116         <Description><![CDATA[%s]]></Description>
117         <PicUrl><![CDATA[%s]]></PicUrl>
118         <Url><![CDATA[%s]]></Url>
119     </item>
120 ";
121         $item_str = "";
122         foreach ($arr_item as $item)
123             $item_str .= sprintf($itemTpl, $item['Title'], $item['Description'], $item['PicUrl'], $item['Url']);
124
125         $newsTpl = "<xml>
126 <ToUserName><![CDATA[%s]]></ToUserName>
127 <FromUserName><![CDATA[%s]]></FromUserName>
128 <CreateTime>%s</CreateTime>
129 <MsgType><![CDATA[news]]></MsgType>
130 <Content><![CDATA[]]></Content>
131 <ArticleCount>%s</ArticleCount>
132 <Articles>
133 $item_str</Articles>
134 </xml>";
135
136         $result = sprintf($newsTpl, $object->FromUserName, $object->ToUserName, time(), count($arr_item));
137         return $result;
138     }
139
140     private function logger($log_content)
141     {
142     }
143 }

三、效果演示

四、如何扩展

1. 在数据库加入邮编、区号、拼音等字段,可以扩展成使用区号等方式查询,请参考:http://www.cnblogs.com/txw1958/archive/2013/02/07/weixin-if4-weather-forecast.html

2. 拥有高级接口的用户,可以使用结合语音识别+中文分词技术,实现语音版的智能查询,请参考:http://www.cnblogs.com/txw1958/archive/2013/02/06/weixin-if40-voice-recognition.html

五、关于接口更新

1. 中国天气网已经停步上述免费接口的更新,需要调用天气数据需要申请SWA接口。

地址 http://smart.weather.com.cn/wzfw/smart/weatherapi.shtml

2. 中国天气网的智慧天气接口在微信公众平台上的实现方法在《微信公众平台开发最佳实践》一书有讲解

地址 http://www.cnblogs.com/txw1958/p/weixin-development-best-practice.html

微信公众平台开发----天气预报相关推荐

  1. 微信公众平台开发 天气预报

    在这篇教程中,我们将介绍如何在微信公众平台上开发天气预报功能.我们将使用中国天气网的气象数据接口来获取天气信息. 这篇教程将介绍以下内容: 获取中国天气网的气象数据 在微信公众平台中回复天气 一.中国 ...

  2. 微信公众平台开发(82) 天气预报

    在这篇教程中,我们将介绍如何在微信公众平台上开发天气预报功能.我们将使用中国天气网的气象数据接口来获取天气信息. 这篇教程将介绍以下内容: 获取中国天气网的气象数据 在微信公众平台中回复天气 一.中国 ...

  3. 天气预报文字版微信_微信公众平台开发(4)天气预报

    微信公众平台 微信公众平台开发 消息接口 微信天气预报 天气预报接口 中国天气网 一.数据接口 百度提供天气预报查询接口API,可以根据经纬度/城市名查询天气情况,我们可以在微信公众平台开发中调用这一 ...

  4. 微信公众平台开发(58)自定义菜单

    微信公众平台开发 微信公众平台开发模式 企业微信公众平台 自定义菜单 开发教程  作者:方倍工作室  地址:http://www.cnblogs.com/txw1958/p/weixin-58-cus ...

  5. 第六篇 :微信公众平台开发实战Java版之如何自定义微信公众号菜单

    我们来了解一下 自定义菜单创建接口: http请求方式:POST(请使用https协议) https://api.weixin.qq.com/cgi-bin/menu/create?access_to ...

  6. 视频教程-微信公众平台开发入门-微信开发

    微信公众平台开发入门 订阅后,请点击此处观看大牛全套视频课程:课程播放页链接 价格可能因活动略有浮动 刘运强 ¥39.00 立即订阅视频课 订阅后:请点击此处观看视频课程 视频教程-微信公众平台开发入 ...

  7. 微信公众平台开发最佳实践(第2版)

    <微信公众平台开发最佳实践 第2版> 微信公众平台开发经典之作全新改版,精心挑选最经典的商业项目开发,成千上万人次微信公众平台开发者从中受益 前言 出版说明 自从方倍工作室在博客园推出微信 ...

  8. 微信公众平台开发最佳实践

    <微信公众平台开发最佳实践>共分10章,案例程序采用广泛流行的PHP.MySQL.XML.CSS.JavaScript.HTML5等程序语言及数据库实现.系统完整地介绍微信公众平台基础接口 ...

  9. 微信公众平台开发(六) 翻译功能开发

    转载自:http://www.php100.com/html/php/api/2013/0909/6130.html 微信公众平台开发(六) 翻译功能开发 来源:David Camp   时间:201 ...

最新文章

  1. JSP中的重定向和请求转发以及它们的区别
  2. 利用IPSec实现网络安全之三(身份验证和加密数据)
  3. Dubbo整合hystrix
  4. 【BootCDN】前端使用开源免费的 CDN 加速服务
  5. 诺基亚对塞班的支持将持续到2016年
  6. 10.python网络编程(socket server 实现并发 part 2)
  7. Blazor Server 应用程序中进行 HTTP 请求
  8. 深度学习“四大名著”发布!Python、TensorFlow、机器学习、深度学习四件套!
  9. 没有Where条件下group by走索引
  10. git:致命的:无法从远程存储库读取
  11. bootstrap 复选框及单选按钮
  12. 四、Oracle的复杂查询
  13. 项目进度管理(下)(重要考点)
  14. 软件工程——软件维护
  15. 软硬件全开源,航芯方案分享 | 热敏打印机方案
  16. 互联网公司干不好上门维修?
  17. Vue中的$event详解
  18. TweenMax.to()的使用
  19. 《微观经济学》 第十章
  20. 超超超详细-实现一个简单的基于 React Fiber 的 React

热门文章

  1. css 世界之条纹背景
  2. 除了安卓模拟器还有什么方式玩刺激战场等吃鸡手游效果好?
  3. 计算机主机内部结构主要有哪几个,电脑硬件组成主要是哪几部分
  4. 智能电视竞争白热化,利用小程序快速共建生态突围
  5. Youtube上面的Red5 官方视频下载教程,带字幕【亲测成功】
  6. C# SendKeys.Send 方法
  7. 精益安灯电子看板实现了实时监测
  8. 后疫情时代,小投资大回报的轻资产项目,Ai智能金刚指欢迎您的考察加盟
  9. omn core 测试网部署
  10. 【css + echarts】实现两种时钟展示