环境:eclipsse, jdk1.6, 没有使用第三方的包,都是JDK有的。
项目结构如下:
1.获取天气预报的类
WeatherUtil.java
[java]
package com.siqi.weather;
import java.io.File;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Hashtable;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
/**
* 中国气象频道手机版("http://m.weathercn.com")获取天气信息, 因为手机版网页内容小,访问速度快。
*
* @author siqi
*
*/
public class WeatherUtil {
/**
* 省份页面(省)
*/
public static final String PROVINCE_URL = "http://m.weathercn.com/common/province.jsp";
/**
* 城市页面(市)
* pid=%s中%s表示城市编号 例:http://m.weathercn.com/common/dis.do?pid=010101
*/
public static final String DISTRICT_URL = "http://m.weathercn.com/common/dis.do?pid=%s";
/**
* 县区页面(区)
* did=%s中%s表示县区编号
* pid=%s中%s表示城市编号
* 例:http://m.weathercn.com/common/cout.do?did=01010101&pid=010101
*/
public static final String COUNTY_URL = "http://m.weathercn.com/common/cout.do?did=%s&pid=%s";
/**
* 7天天气预报页面
* cid=%s中%s表示区编号
* 例:http://m.weathercn.com/common/7d.do?cid=0101010110
*/
public static final String REPORT7_URL = "http://m.weathercn.com/common/7d.do?cid=%s";
/**
* 生活指数页面
* cid=%s中%s表示区编号
*/
public static final String REPORT_MORE_URL = "http://m.weathercn.com/common/zslb.do?cid=%s";
/**
* 保存城市编码信息的xml文档
* 保存了具体的区县和区县所对应的编码,例如
*
* 北京
* 0101010110
*
*/
public static final String XML_FILE = "./weathercn.xml";
private List weatherReportList = new ArrayList();
/**
* 启动的时候,首先检查weathercn.xml是否存在,如果不存在的话,重新从m.weathercn.com获取,
* 只有第一次的时候会获取。
*/
static {
try {
prepareXML();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 返回指定城市,指定日期的天气预报。
*
* @param city
* 城市,如"北京"。
* @param cal
* 日期。
* @return 如果城市正确,并且日期在7天以内,那么返回天气信息。否则返回null。
*/
public WeatherReport getWeatherReport(String city, Calendar cal) {
String dateStr = cal.get(Calendar.MONTH) + "月"
+ cal.get(Calendar.DAY_OF_MONTH) + "日";
return getWeatherReport(city, dateStr);
}
/**
* 返回指定城市,指定日期的天气预报。
*
* @param city
* 城市,如"北京"。
* @param date
* 日期,格式为"1月20日"。
* @return 如果城市正确,并且日期在7天以内,那么返回天气信息。否则返回null。
*/
public WeatherReport getWeatherReport(String city, String date) {
for (WeatherReport report : getWeatherReports(city)) {
if (report.getDate().equals(date)) {
return report;
}
}
return null;
}
/**
* 返回指定城市的天气预报(7天内)
*
* @param city
* @return 返回指定城市的天气预报(7天内),如果指定的城市错误,返回空的list,list.size()=0
*/
public List getWeatherReports(String city) {
List list = new ArrayList();
try {
String weatherPage = getWeatherReportPage(city);
List reportStrList = getAllMathers(weatherPage,
"(?<=class="b">)[\s\S]+?
[\s\S]+?(?=)");
for (String reportStr : reportStrList) {
String weather = reportStr.trim().replaceAll(" ", "")
.replaceAll("
rnrn", "rn")
.replaceAll("
", "");
String[] str = weather.split("rn");
if (str.length > 5) {
WeatherReport report = new WeatherReport();
int i = 0;
String dateStr = str[i++].trim();
report.setCity(city);
report.setDate(getMatcher(dateStr, ".+(?=\()"));
report.setWeekDay(getMatcher(dateStr, "(?<=\().+?(?=\))"));
report.setDayOrNight(str[i++].trim());
report.setWeather(str[i++].trim());
report.setTemperature(str[i++].trim());
report.setWindDir(str[i++].trim());
report.setWind(str[i++].trim());
list.add(report);
if (str.length > 10) {
report = new WeatherReport();
report.setCity(city);
report.setDate(getMatcher(dateStr, ".+(?=\()"));
report.setWeekDay(getMatcher(dateStr,
"(?<=\().+?(?=\))"));
report.setDayOrNight(str[i++].trim());
report.setWeather(str[i++].trim());
report.setTemperature(str[i++].trim());
report.setWindDir(str[i++].trim());
report.setWind(str[i++].trim());
list.add(report);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
this.weatherReportList = list;
return thi