生成统计成都市商品房成交量的bar chart.
一直想得到成都市的商品房交易数据来进行一些分析。但苦于没有数据来源。这个想法一直被搁浅在那儿。偶然的机会知道成都市每日的成交量在发布当天的成效数据。
http://www.agoit.com/upload/picture/pic/90523/f0a9a515-832f-3b7a-a4cd-0e112224ecb9.jpg
就突发奇想想做一个页面抓取工具,能将每天的成交数据统计分析。可以该网站并不提供历史数据的查询,很是郁闷。
不过偶然的机会又发现另一个网站已经提供了部分历史数据的统计:
http://www.agoit.com/upload/picture/pic/90535/dfc9039e-b394-397b-a0df-47fbc3f24e29.jpg
虽然通过页面的按钮只能找到10个可用的页面,但通过改变url中的page参数,我们可以找到最多75面的有效数据。
找到数据的来源了,接下来的问题就是如何从页面中抓取到想要的数据了。
这是查看到的相关的页面结构:
http://www.agoit.com/upload/picture/pic/90541/66cddf47-6ecd-3cc7-8bc6-819ba754a980.jpg
想要的信息有两个:1.日期 2.成交套数
一开始我想到的是将页面用DOM解析出来,然后通过xpath来找到想要的数据。
放弃这种的原因有:
[*]并不是所有的网页都采用的是XHtml,很可能会解析出错。
[*]利用现有大多支持XPath,查找HTML的框架都需要先做额外的工作将网页保存起来,才能进行解析,过于麻烦。
在花了些时间后,google到了jsoup这个目前非常流行的parser。
虽然不支持xpath,但它支持类似于jquery的selector来选取内容。而且可以直接通过url来解析网页。
以下是得用jsoup的代码:
public class GetHouseStatistics { public static void main(String[] args) throws Exception { String url = "http://newhouse.cd.soufun.com/house/web/newhouse_news_more.php?type=12193&page="; FileWriter writer = new FileWriter(new File("house.data")); for (int i = 1; i < 75; i++) { Document doc = Jsoup.connect(url + i).timeout(9000).get(); Elements me = doc.select(""); System.out.println(me.html()); writer.append(me.html()+"\n"); } writer.close(); }}
以下是运行得到的结果保存成一个csv文件:
市区5月17日商品住宅成交158套成都市区5月15日商品住宅成交41套[成都房地产成交量]市区5月11日商品住宅成交182套[成都房地产成交量]市区5月10日商品住宅成交183套[成都房地产成交量]市区5月9日商品住宅成交163套[成都房地产成交量]市区5月8日商品住宅成交53套[成都房地产成交量]市区5月7日商品住宅成交44套[成都房地产成交量]市区5月3日商品住宅成交171套[成都房地产成交量]市区5月2日商品住宅成交31套[成都房地产成交量]市区5月1日商品住宅成交31套[成都房地产成交量]市区4月30日商品住宅成交85套[成都房地产成交量]市区4月29日商品住宅成交219套[成都房地产成交量]市区4月28日商品住宅成交230套[成都房地产成交量]市区4月27日商品住宅成交170套[成都房地产成交量]市区4月25日商品住宅成交92套[成都房地产成交量]市区4月26日商品住宅成交104套......现在需要将日期和成交套数从文件中提取出来生成新的csv文件。
下面是代码:
public class Data2CVS { public static void main(String[] args) throws Exception { BufferedReader bufferedReader = new BufferedReader(new FileReader(new File("house.data"))); BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(new File("house.cvs"))); int year = 2011; String lineData; while ((lineData = bufferedReader.readLine()) != null) { Pattern p = Pattern.compile("\\d+月\\d+日"); Matcher m = p.matcher(lineData); while (m.find()) { String date = m.group().trim(); bufferedWriter.append(year+"年"+date); bufferedWriter.append("\t"); if(date.equals("01月01日")||date.equals("1月1日")){ year--; } } p = Pattern.compile("\\d+套"); m = p.matcher(lineData); while (m.find()) { String date = m.group().replace("套", ""); bufferedWriter.append(date); bufferedWriter.append("\n"); } } bufferedReader.close(); bufferedWriter.close(); }}运行得到的新的CSV文件为:
2011年5月17日1582011年5月15日412011年5月11日1822011年5月10日1832011年5月9日1632011年5月8日532011年5月7日442011年5月3日1712011年5月2日312011年5月1日312011年4月30日852011年4月29日2192011年4月28日2302011年4月27日1702011年4月25日922011年4月26日1042011年4月24日412011年4月23日62
得到CSV文件,就可以很方便的利用各种工具来生成图表了。以下是利用WPS报表生成的bar chart:
http://www.agoit.com/upload/picture/pic/90543/10a95eea-b7a8-3b1e-8292-1e9d60d71b02.jpg
页:
[1]