【实践】基于百度地图API实现的地图形式天气预报【一】主要介绍了前端地图显示页面的实现,现在介绍下服务端城市天气信息的获取方法。
最近在学php语言,也算入了门了,所以此脚本是用php实现的也算是练习练习。该脚本主要实现两个功能一个是根据客户端提交来的城市名称从网上抓取该城市的天气信息,另一个功能是格式化天气信息便于前端显示。
天气信息抓取是通过向百度搜索页面提交城市名称+天气组成的关键字(如“北京天气”),获得搜索后的页面内容,再在该页面内容中利用正则抓取出天气信息。
<?php $city = $_GET["a"]; /** * 功能: 根据输入的城市名进行天气查询并提取出天气信息 * 参数: $city为该城市名称 * 说明: 返回三天天气信息数组 */ function get_city_weather($city){ $w=array(); if(!mb_detect_encoding($city,"utf-8")){ $city=mb_convert_encoding($city, "utf-8", "gbk"); } $url = 'http://www.baidu.com/s?wd=' . $city . '天气'; $lines = file($url); $contents = file_get_contents ($url); $contents = mb_convert_encoding($contents, "utf-8", "gbk"); $w["city"]=$city; preg_match('/中国天气网(.*?)中国气象局/', $contents, $contents_string); $lines_string = $contents_string[1]; $w["img"]=array(); preg_match_all('/<img(.*?)\/>/', $lines_string, $images); for ($i = 0; $i < (count($images[0])/2); $i++) { preg_match('/src=(.*?)\/>/',$images[0][$i*2],$array_images1); preg_match('/src=(.*?)\/>/',$images[0][$i*2+1],$array_images2); $w["img"][$i]=array($array_images1[1],$array_images2[1]); } preg_match_all('/<\/div>(.*?)<span>/', $lines_string, $weather); for ($i = 0; $i < count($weather[0]); $i++) { preg_match('/(.*?)℃/', strip_tags($weather[0][$i]), $array_temperature); $temperature[$i] = $array_temperature[0]; preg_match('/℃(.*)/', strip_tags($weather[0][$i]), $array_tianqi); $tianqi[$i] = $array_tianqi[1]; } $w["temperature"]=$temperature; $w["weather"]=$tianqi; preg_match_all('/<span>(.*?)<\/span>/', $lines_string, $wind); for ($i = 0; $i < count($wind[0]); $i++) { $w["wind"][$i]=strip_tags($wind[0][$i]); } return $w; }
其中有两处关于编码转换问题,第一处对提交来的$city变量进行编码检查,刚开始我此处我并未这样做因为我是在firefox浏览器下进行测试未发现任何问题,后来我在ie上进行测试时发现了提交数据是乱码的问题,想起以前看过的一篇文章介绍过firefox和ie在提交数据时默认采用了不同的编码,firefox默认是采用utf-8而ie是gbk,我写的前端地图显示页面和后台php脚本都是统一的uft-8编码,所以才出现了ie上的乱码问题,后来在此处添加了编码检查,现用mb_detect_encoding函数进行编码检查,不是utf-8就再利用mb_convert_encoding函数进行编码转换。另一处是对百度天气搜索返回的页面内容进行编码转换,这是因为百度页面编码是gb2312,转换为utf-8进行统一以防乱码。
后面要做的就是对百度搜索返回的页面内容利用正则表达式进行天气信息提取,这里的关键就是编写正则表达式,正好提取出想要的天气信息,在这里自己先前也是没多少经验,只能比对这页面内容不断进行尝试,最后利用preg_match和preg_match_all函数配合自己编写的正则达到了目的,提取出了下图所示红框中的天气信息。
再后面要做的就是编写html与css代码,对天气信息进行显示,这当然要与前端地图显示页面的信息窗口相符合,信息窗口的内容就是此处服务端返回给地图显示页面的html代码。
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <style type="text/css"> body{margin:0 auto;padding:0;background:none repeat scroll 0 0 #F8FAFC;} .div_content{ width:400px; background:none repeat scroll 0 0 #FFFFFF; height:135px; margin:0; padding:0; } table{ font-family:arial; font-size:100%; } td{ font-size:14px; text-align:center; } .td_lf{ padding-right:20px; } .td_center{ padding-right:20px; padding-left:20px; border-left:1px solid #E2E9FC; } .td_rt{ padding-left:20px; border-left:1px solid #E2E9FC; } strong{ white-space:nowrap; } </style> </head> <body> <div class="div_content"> <table cellspacing="0" cellpadding="0"> <tr> <td class="td_lf"> <strong>今天</strong> <br /> <div> <img src=<?php echo $w["img"][0][0]; ?>/> <img src=<?php echo $w["img"][0][1]; ?>/> </div> <strong><?php echo $w['temperature'][0]; ?></strong> <br /> <strong><?php echo $w['weather'][0]; ?></strong> <br /> <strong><?php echo $w['wind'][0]; ?></strong> </td> <td class="td_center"> <strong>明天</strong> <br /> <div> <img src=<?php echo $w["img"][1][0]; ?>/> <img src=<?php echo $w["img"][1][1]; ?>/> </div> <strong><?php echo $w['temperature'][1]; ?></strong> <br /> <strong><?php echo $w['weather'][1]; ?></strong> <br /> <strong><?php echo $w['wind'][1]; ?></strong> </td> <td class="td_rt"> <strong>后天</strong> <br /> <div> <img src=<?php echo $w["img"][2][0]; ?>/> <img src=<?php echo $w["img"][2][1]; ?>/> </div> <strong><?php echo $w['temperature'][2]; ?></strong> <br /> <strong><?php echo $w['weather'][2]; ?></strong> <br /> <strong><?php echo $w['wind'][2]; ?></strong> </td> </tr> </table> </div> </body> </html>
显示效果如下图:
最后,就是在地图显示页面,弹出的信息窗口中显示天气信息了,最终效果图:
最后,还提下存在的问题,就是在ie中显示的效果问题,在ie中信息窗口中的内容是无样式的排列,如下图:
这个问题折腾了很久也没解决,浏览器之间的兼容问题还真令人感到纠结啊,自己现在也只能不断积累经验,待日后解决。