0 项目说明
宜居城市信息可视化平台
提示:适合用于课程设计或毕业设计,工作量达标,源码开放
1 研究目的
通过搜集城市相关数据,减少用户收集信息的时间,并为用户选择心目中的宜居城市提供更有利的依据。
2 研究方法
通过网络爬虫就城市的招聘、租房、城市的气候、空气质量指数、美食、旅游景点等等数据进行爬取入库,最后再进行数据的分析统计处理,并通过web可视化的方式展现这些信息变化的特征。
3 数据来源
3.1招聘信息
招聘信息的数据来源为智联招聘,首先构造出城市+工作职位的url,以便我们更好的搜索数据和解析页面数据。例如http://sou.zhaopin.com/jobs/searchresult.ashx?jl=北京&kw=java(jl后边的是城市,kw为职位名),根据此url解析第一页获取工作数量,智联招聘一页最多显示60条工作职位的信息,一共显示90页,所以我们根据获取的工作数量来确定需要抓取数据的页数,条数大于90页的则获取90页,小于90页的则使用实际页数。然后根据页数构建出最终的url:http://sou.zhaopin.com/jobs/searchresult.ashx?jl=北京&kw=java&p=1(p为页码)最后抓取每一页上对应具体工作的url所对应的工作信息及其公司信息。统计出最大工资与最小工资的平均工资,中位数工资,以及工资和工作经验的关系等
3.2 房租信息
房租信息数据主要来源于赶集网,同样首先构建出对应城市url,例如:
http://{}.ganji.com/fang1/o{}/
(第一个{}表示城市的汉子拼音首字母,第二个{}为页数),这里我们只抓取30页。统计出该城市有哪些中介公司,房屋的朝向和价格的关系,计算出每平米的价格等等。
3.3 城市气候信息
气候信息数据主要来源于天气网,构建出的url为http://lishi.tianqi.com/{}/index.html({}为城市汉子的拼音)。抓取该城市自2011-01-01以来的所有天气信息。统计出对应的历史天气,风向、风力以及每月的气温变化等。
3.4 空气质量指数信息
AQI信息数据主要来源于中国空气质量在线监测分析平台历史数据网,构建出的url为https://www.aqistudy.cn/historydata/monthdata.php?city=北京 PM2.5历史数据网的数据主要是2013年12月到现在的数据。抓取每个月的数据统计量以及每月对应每天的数据量。统计AQI月变化的趋势以及等级月变化的趋势,统计等级的月数和天数。
3.5 旅游景点信息
景点信息数据主要来源于欣欣旅游网,构建的url为:http://{}.cncn.com/jingdian/1-{}-0-0.html (第一个{}为城市名的拼音,第二个{}为页数),首先抓取对应的页数,然后再针对每一页抓取当前城市的所有景点信息。将对应的景点的照片下载到本地,列表展示景点信息,统计出景点的热度排名。
3.6 美食信息
美食信息数据也来源于欣欣旅游网,构建的url为:http://{}.cncn.com/meishi/index{}.htm (第一个{}为城市名的拼音,第二个{}为页数)。同样先抓取页数,如果所抓取的页数为空,则说明只有一页。抓取该城市的所有美食信息,将美食图片下载到本地,列表展示之,并根据热度进行排名。
4 项目源码
package com.cityview.controller;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.cityview.po.Aqiday;
import com.cityview.po.AqidayCustom;
import com.cityview.po.Aqimonth;
import com.cityview.po.AqimonthCustom;
import com.cityview.po.AqimonthQueryVo;
import com.cityview.service.AqimonthService;
import com.cityview.spider.AOI;
/**
* <p>Title: AqimonthController.java</p>
* <p>Description:月全量controller </p>
* @version 1.0cityview
*/
@Controller
@RequestMapping("/aqimonth")
public class AqimonthController {
@Autowired
private AqimonthService aqimonthService;//注入service
//历史空气质量指数月全量查询
//@RequestMapping实现 对queryItems方法和url进行映射,一个方法对应一个url
//一般建议将url和方法写成一样.action可加可不加
/**
* 空气质量指数查询(月全量)
* @param aqimonth
* @return
* @throws Exception
*/
@RequestMapping("/table")
public @ResponseBody List<Aqimonth> queryAqimonth(@RequestBody Aqimonth aqimonth) throws Exception{
System.out.println("------空气质量指数查询start-----"+aqimonth.getCityname());
List<Aqimonth> aqimonthlist=aqimonthService.findAqimonthList(aqimonth);
// if(aqimonthlist.size()==0){
// aqimonthlist.add(null);
// }
System.out.println("------空气质量指数查询查询end-----");
//@ResponseBody将itemsCustom转成json输出
return aqimonthlist;
}
/**
* 批量操作,将AQI相关数据爬过来批量插入数据库
* @return
* @throws Exception
*/
@RequestMapping("/insert")
public @ResponseBody String insertAqimonth(@RequestBody Aqiday aqiday) throws Exception{
AOI aqi=new AOI();
List<Aqimonth> aqiList=aqi.insertAqimonth(aqiday.getCityname());
List<Aqimonth> queryaqiList=new ArrayList<Aqimonth>();//新的list存入数据库
for(Aqimonth list:aqiList){
if(aqimonthService.findAqi(list.getAqiurl())!=1){
queryaqiList.add(list);
List<Aqiday> aqidaylist=aqi.insertAqiday(list.getCityname(),list.getMonth());
if(aqidaylist.size()>0){
aqimonthService.insertAqidayList(aqidaylist);
}
}
}
System.out.println(aqiList.size());
if(queryaqiList.size()>0){
System.out.println(queryaqiList.toString()+"插入空气质量指数");
aqimonthService.insertAqimonthList(queryaqiList);
}
return "成功";
}
// //限制http请求方法,可以post和get
// @RequestMapping("/queryAqiDay")
// public ModelAndView queryAqiDay(HttpServletRequest request) throws Exception{
// String cityname=request.getParameter("cityname");
// String month=request.getParameter("month");
// System.out.println(cityname+">>>>>>>>>>>>>>>>>>>>>"+month);
// //调用service查找数据库,查询每月数据列表
// Aqiday aqiday=new Aqiday();
// aqiday.setCityname(cityname);
// aqiday.setDay(month);
//
// List<Aqiday> aqidaysList = aqimonthService.findaqidayList(aqiday);
//
// //返回ModelAndView
// ModelAndView modelAndView=new ModelAndView();
//
// //此方法相当于request的setAttribute()方法,在jsp中通过itemsList取数据
// modelAndView.addObject("aqidaysList", aqidaysList);
//
// //指定视图
// //下边的路径,如果在视图解析器中配置jsp路径的前缀和jsp路径的后缀,修改为
// //modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
// //上边的路径配置可以不在程序中指定jsp路径的前缀和jsp路径的后缀
// modelAndView.setViewName("aqi/dayaqi");
// return modelAndView;
// }
/**
* 查询AQI当月日全量
* @param aqiday
* @return
* @throws Exception
*/
@RequestMapping("/queryAqidayAll")
public @ResponseBody List<Aqiday> queryAqidayAll(@RequestBody Aqiday aqiday) throws Exception{
System.out.println("====================查询当月每天的AQI=========="+aqiday.getCityname()+aqiday.getDay());
List<Aqiday> aqidaylist=aqimonthService.findaqidayList(aqiday);
return aqidaylist;
}
/**
* 根据传入的cityname和月份
* @param aqiday
* @return 返回统计对应的天气状况及对应的总天数
* @throws Exception
*/
@RequestMapping("/queryAqidayCountGrade")
public @ResponseBody List<AqidayCustom> queryAqidayCountGrade(@RequestBody Aqiday aqiday) throws Exception{
System.out.println("===================每月AQI质量等级天数统计=========="+aqiday.getCityname()+aqiday.getDay());
List<AqidayCustom> aqidayCustomsList=aqimonthService.findCountGrade(aqiday);
for(AqidayCustom li:aqidayCustomsList){
System.out.println(li.getGrade()+"<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"+li.getNumGrade());
}
return aqidayCustomsList;
}
//一对多映射
/**
* 根据传入的城市统计每个月不同质量等级的天数
* @param aqimonthCustom
* @return
* @throws Exception
*/
@RequestMapping("/queryAqiMonthCountGrade")
public @ResponseBody List<AqimonthQueryVo> queryAqiMonthCountGrade(@RequestBody AqimonthCustom aqimonthCustom) throws Exception{
System.out.println("===================每月AQI质量等级天数统计=========="+aqimonthCustom.getCityname());
List<AqimonthQueryVo> aqimonthQuerylist=new ArrayList<AqimonthQueryVo>();//需要返回的数据
Map<String,String> map=new HashMap<String, String>();
//以下是数据库传过来的数据
List<AqimonthQueryVo> aqimonthQueryVoList=aqimonthService.findAqiMonthCountGrade(aqimonthCustom);
for(AqimonthQueryVo li:aqimonthQueryVoList){
System.out.println(li.getMonthday()+"-------------->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
AqimonthQueryVo aqimonthQueryVo=new AqimonthQueryVo();
aqimonthQueryVo.setMonthday(li.getMonthday());//将查询出来的月份重新设置
List<AqimonthCustom> aqimonthCustomList=li.getAqimonthCustoms();
map.put("严重污染", "0");
map.put("重度污染", "0");
map.put("中度污染", "0");
map.put("轻度污染", "0");
map.put("良", "0");
map.put("优", "0");
for(AqimonthCustom aqili:aqimonthCustomList){
//System.out.println(aqili.getGrade()+":"+aqili.getNumGrade()+"天");
map.put(aqili.getGrade(), aqili.getNumGrade());
}
List<AqimonthCustom> aqimonthCustoms=new ArrayList<AqimonthCustom>();
//输出map出来看看
Set<String> set = map.keySet();
Iterator<String> it = set.iterator();
while (it.hasNext()) {
String Typekey = it.next();
String Typevalue = map.get(Typekey);
AqimonthCustom aqimonthCustombean=new AqimonthCustom();
aqimonthCustombean.setGrade(Typekey);
aqimonthCustombean.setNumGrade(Typevalue);
aqimonthCustoms.add(aqimonthCustombean);
System.out.println("这是map中的:"+Typekey+"->>"+Typevalue);
}
aqimonthQueryVo.setAqimonthCustoms(aqimonthCustoms);
aqimonthQuerylist.add(aqimonthQueryVo);
System.out.println("--------------分割线----------------------------");
}
return aqimonthQuerylist;
}
/**
* 统计历史以来不同质量等级的天数
* @param aqiday
* @return
* @throws Exception
*/
@RequestMapping("/queryCountGradeDay")
public @ResponseBody List<AqidayCustom> queryCountGradeDay(@RequestBody Aqiday aqiday) throws Exception{
List<AqidayCustom> aqidayCustoms=aqimonthService.findCountGradeDay(aqiday);
return aqidayCustoms;
}
/**
* 查询质量等级不同的月数
* @param aqimonth
* @return
* @throws Exception
*/
@RequestMapping("/queryCountGradeMonth")
public @ResponseBody List<AqimonthCustom> queryCountGradeMonth(@RequestBody Aqimonth aqimonth) throws Exception{
List<AqimonthCustom> aqimonthCustoms=aqimonthService.findCountGradeMonth(aqimonth);
return aqimonthCustoms;
}
}
5 最后
**项目分享: ** https://gitee.com/asoonis/htw