点击这里给我发消息 点击这里给我发消息

微信公众帐号开发教程第16篇-应用实例之历史上的今天

添加时间:2014-4-10
    相关阅读: 网页 开发 页面 网络 HTML 网站
       本篇文章主要讲解如何在微信公众帐号上实现“历史上的今天”功能。这个例子本身并不复杂,但希望通过对它的学习,读者能够对正则表达式有一个新的认识,能够学会运用现有的网络资源丰富自己的公众账号。
      何谓历史上的今天
      回顾历史的长河,历史是生活的一面镜子;以史为鉴,可以知兴衰;历史上的每一天,都是喜忧参半;可以了解历史的这一天发生的事件,借古可以鉴今,历史是不能忘记的。查看历史上每天发生的重大事情,增长知识,开拓眼界,提高人文素养。
      寻找接口(数据源)
要实现查询“历史上的今天”,首先我们要找到相关数据源。笔者经过搜索发现,网络上几乎没有现成的“历史上的今天”API可以使用,所以我们只能通过爬取、解析网页源代码的方式得到我们需要的数据。笔者发现网站http://www.rijiben.com/上包含“历史上的今天”功能,就用它做数据源了。
       开发步骤
为了便于读者理解,我们需要清楚该应用实例的开发步骤,主要如下:
1)发起HTTP GET请求,获取网页源代码。
2)运用正则表达式从网页源代码中抽取我们需要的数据。
3)对抽取得到的数据进行加工(使内容呈现更加美观)。
4)将以上三步进行封装,供外部调用。
5)在公众账号后台调用封装好的“历史上的今天”查询方法。
      代码实现
      笔者将上述步骤1)、2)、3)中的代码实现封装成了TodayInHistoryService类,并对外提供了getTodayInHistory()方法来获取“历史上的今天”。实现代码如下:
[java] view plaincopy
import java.io.BufferedReader;  
import java.io.InputStream;  
import java.io.InputStreamReader;  
import java.net.HttpURLConnection;  
import java.net.URL;  
import java.text.DateFormat;  
import java.text.SimpleDateFormat;  
import java.util.Calendar;  
import java.util.regex.Matcher;  
import java.util.regex.Pattern;  
  
/** 
 * 历史上的今天查询服务 
 *  
 * @author liufeng 
 * @date 2013-10-16 
 *  
 */  
public class TodayInHistoryService {  
  
    /** 
     * 发起http get请求获取网页源代码 
     *  
     * @param requestUrl 
     * @return 
     */  
    private static String httpRequest(String requestUrl) {  
        StringBuffer buffer = null;  
  
        try {  
            // 建立连接  
            URL url = new URL(requestUrl);  
            HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();  
            httpUrlConn.setDoInput(true);  
            httpUrlConn.setRequestMethod("GET");  
  
            // 获取输入流  
            InputStream inputStream = httpUrlConn.getInputStream();  
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");  
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);  
  
            // 读取返回结果  
            buffer = new StringBuffer();  
            String str = null;  
            while ((str = bufferedReader.readLine()) != null) {  
                buffer.append(str);  
            }  
  
            // 释放资源  
            bufferedReader.close();  
            inputStreamReader.close();  
            inputStream.close();  
            httpUrlConn.disconnect();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return buffer.toString();  
    }  
  
    /** 
     * 从html中抽取出历史上的今天信息 
     *  
     * @param html 
     * @return 
     */  
    private static String extract(String html) {  
        StringBuffer buffer = null;  
        // 日期标签:区分是昨天还是今天  
        String dateTag = getMonthDay(0);  
  
        Pattern p = Pattern.compile("(.*)(<div class=\"listren\">)(.*?)(</div>)(.*)");  
        Matcher m = p.matcher(html);  
        if (m.matches()) {  
            buffer = new StringBuffer();  
            if (m.group(3).contains(getMonthDay(-1)))  
                dateTag = getMonthDay(-1);  
  
            // 拼装标题  
            buffer.append("≡≡ ").append("历史上的").append(dateTag).append(" ≡≡").append("\n\n");  
  
            // 抽取需要的数据  
            for (String info : m.group(3).split("  ")) {  
                info = info.replace(dateTag, "").replace("(图)", "").replaceAll("</?[^>]+>", "").trim();  
                // 在每行末尾追加2个换行符  
                if (!"".equals(info)) {  
                    buffer.append(info).append("\n\n");  
                }  
            }  
        }  
        // 将buffer最后两个换行符移除并返回  
        return (null == buffer) ? null : buffer.substring(0, buffer.lastIndexOf("\n\n"));  
    }  
  
    /** 
     * 获取前/后n天日期(M月d日) 
     *  
     * @return 
     */  
    private static String getMonthDay(int diff) {  
        DateFormat df = new SimpleDateFormat("M月d日");  
        Calendar c = Calendar.getInstance();  
        c.add(Calendar.DAY_OF_YEAR, diff);  
        return df.format(c.getTime());  
    }  
  
    /** 
     * 封装历史上的今天查询方法,供外部调用 
     *  
     * @return 
     */  
    public static String getTodayInHistoryInfo() {  
        // 获取网页源代码  
        String html = httpRequest("http://www.rijiben.com/");  
        // 从网页中抽取信息  
        String result = extract(html);  
  
        return result;  
    }  
  
    /** 
     * 通过main在本地测试 
     *  
     * @param args 
     */  
    public static void main(String[] args) {  
        String info = getTodayInHistoryInfo();  
        System.out.println(info);  
    }  
}  
代码解读:
1)27-58行代码是httpRequest()方法,用于发起http get请求,获取指定url的网页源代码。
2)66-92行代码是extract()方法,运用正则表达式从网页源代码中抽取“历史上的今天”数据。
3)111-118行代码是getTodayInHistory()方法,封装给外部调用查询“历史上的今天”。
4)125-128行代码是main方法,用于在本地的开发工具中测试。
         5)75-76行代码的作用是判断获取到的“历史上的今天”数据是当天的还是前一天的(因为不能保证www.rijiben.com上的数据一定在凌晨零点准时更新,所以为了保证数据的准确性必须做此判断)。
         6)第71行代码是本文的重点,笔者编写的正则表达式规则是“(.*)(<div class=\"listren\">)(.*?)(</div>)(.*)”。正则表达式规则需要根据网页源代码进行编写的,特别是包含“历史上的今天”数据的那部分HTML标签,所以我们先来查看网页源代码。通过httpRequest("http://www.rijiben.com/")方法获取到的网页源代码,与我们通过浏览器访问http://www.rijiben.com/页面再点击右键选择“查看网页源代码”所得到的结果完全一致。我们通过浏览器查看http://www.rijiben.com/的网页源代码,然后找到“历史上的今天”数据所在位置,如下图所示:

咨询热线:020-85648757 85648755 85648616 0755-27912581 客服:020-85648756 0755-27912581 业务传真:020-32579052
广州市网景网络科技有限公司 Copyright◎2003-2008 Veelink.com. All Rights Reserved.
广州商务地址:广东省广州市黄埔大道中203号(海景园区)海景花园C栋501室
= 深圳商务地址:深圳市宝源路华丰宝源大厦606
研发中心:广东广州市天河软件园海景园区 粤ICP备05103322号 工商注册