阅读(2663) (0)

wx-tools 完善菜单栏的功能

2017-01-28 12:41:52 更新

2.6.1 按钮[分类-飙升榜]

需求:当用户点击此按钮,后台爬虫帮我爬当天酷狗飙升榜的列表下来,并返回。 酷狗飙升榜在这。

  • 爬虫技术不是本文档的主要内容,所以在此就不细讲如何爬下数据。有兴趣的同学可以阅读下源代码。(原理很简单,仅仅使用HttpClient+Jsoup)

添加RankHandler.java

此handler专门处理爬虫分类Event事件。

RankHandler.java:(负责处理消息部分)

public class RankHandler implements WxMessageHandler {
    private static RankHandler instance = null;
    private boolean isRun = false;
    private RankHandler() {}

    
    public static synchronized RankHandler getInstance() {
        if (instance == null) {
            instance = new RankHandler();
        }
        return instance;
    }


    @Override
    public WxXmlOutMessage handle(WxXmlMessage wxMessage, Map<String, Object> context, IService iService)
            throws WxErrorException {
        StringBuilder result = new StringBuilder();
        if (!getIsRun()) {
            setRun(true);
            try {
                result = execute(wxMessage);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                setRun(false);
            }
        } else {
            result.append(ResponseConst.DUPLICATE_REQUEST);
        }
        return WxXmlOutMessage.TEXT().content(result.toString()).toUser(wxMessage.getFromUserName()).fromUser(wxMessage.getToUserName()).build();
    }


    private StringBuilder execute(WxXmlMessage wxMessage) throws Exception{
        StringBuilder stringBuilder = new StringBuilder();
        try {
            switch (wxMessage.getEventKey()) {
                case MenuKey.HOT_SONG:
                    collectSongRank(stringBuilder, UrlConst.HOT_RANK_URL);
                    break;
                default:
                    stringBuilder.append("暂时无此分类噢!");
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return stringBuilder;
    }


    private void collectSongRank(StringBuilder stringBuilder, String url) throws IOException {
        RankCollector collector = new RankCollector();
        Rank rank = collector.collect(url);
        stringBuilder.append("\uD83D\uDD25" + rank.getScope() + "[" + rank.getUpdateTime() + "]\n\n");
        for (HotSinger hotSinger : rank.getHotSingerList()) {
            stringBuilder.append(hotSinger.getName() + "-" + hotSinger.getHotSong() + "\n");
        }
    }


    private synchronized boolean getIsRun() {
        return isRun;
    }


    private synchronized void setRun(boolean run) {
        isRun = run;
    }


}

RankCollector.java: (爬虫部分)

public class RankCollector {


    public Rank collect(String url) throws IOException {
        return getRank(url);
    }


    private Rank getRank(String rankUrl) throws IOException {
        Rank rank = new Rank();
        String body = HttpClientUtil.get(rankUrl);
        Document doc = Jsoup.parse(body);
        rank.setScope(doc.select("a[class=current]").attr("title"));
        rank.setUpdateTime(doc.select("span[class=rank_update]").text());
        List<Element> aElements = doc.select("a[data-active=playDwn]");
        for(int i = 0; i < aElements.size(); i++){
            String[] splitArray = aElements.get(i).text().split("-");
            String name = splitArray[0].toString().trim();
            String song = splitArray[1].toString().trim();
            rank.getHotSingerList().add(new HotSinger(doc.select("a[class=current]").attr("title"), name, song));
        }
        return rank;
    }
}

添加新的规则(Rule)

修改新增WxController的路由规则:

router.rule().event(WxConsts.EVT_CLICK).eventKey(MenuKey.HELP).handler(HelpDocHandler.getInstance()).next()
                    .rule().eventKey(MenuKey.HOT_SONG).handler(RankHandler.getInstance()).end();

  • 这里解释一下:next()和end()的意思。
  • next() 表示消息经过第一个规则(Rule)之后,允许继续匹配下面的规则,代表着同一个消息有可能被多个Handler处理。
  • end() 表示规则的结束。当消息满足某条规则时遇到end(),不会再往下匹配规则,就此结束。

重新运行,并测试

HotSong

当天的飙升榜就这样返回回来了~很激动有木有!

  • 好了同一原理实现其他4个排行榜按钮的功能,这里就不展示了。详情可以查看demo源码。