微信快速开发框架(五)-- 利用快速开发框架,快速搭建微信浏览博客园首页文章

简介: 这几天接连发布了《快速开发微信公众平台框架---简介》和《体验微信公众平台快速开发框架》几篇关于微信平台的文章,不过反响一般,可能需求不是很多吧。闲来无事,还是继续改造一下这个框架。 今天更新了框架代码,听取了 @RMay 的建议,加入了一个信息中间件,用来处理xelement,避免了重复解析,所以所有接口都更改了下。

这几天接连发布了《快速开发微信公众平台框架---简介》和《体验微信公众平台快速开发框架》几篇关于微信平台的文章,不过反响一般,可能需求不是很多吧。闲来无事,还是继续改造一下这个框架。

今天更新了框架代码,听取了 @RMay 的建议,加入了一个信息中间件,用来处理xelement,避免了重复解析,所以所有接口都更改了下。此次更新如下:

1、增加信息中间件MiddleMessage

2、更改了接口参数类型,把原来的XElement都改成了MiddleMessage

3、删除了Demo项目,以后都用WebDemo进行演示。

所有代码都已经更新到我的Gibhub

介绍了更新内容,下面继续打造我们的Demo项目。

之前我们写的,都是返回文本信息,今天上午,我加入了一个CnblogsArticleNewsMessageHandler,主要是返回一个ResponseNewsMessage(图文信息),只要发消息:博客园文章,就能获取在首页前5的文章列表,但为了避免给博客园造成鸭梨,我把信息缓存了下,10分钟更新一次。这次主要采用了webclient+正则的方式,采集的方式无所谓,大家都可以自由发挥。

先看下CnblogsArticleNewsMessageHandler:

public class CnblogsArticleNewsMessageHandler : IMessageHandler
    {
        public ResponseMessage HandlerRequestMessage(MiddleMessage msg)
        {
            //var request = new RequestTextMessage(xml);
            var response = new ResponseNewsMessage(msg.RequestMessage);
            var cnblogsFeed = new CnBlogsFeed(5);
            var articles = cnblogsFeed.GetTopCnblogsFeed();
            response.ArticleCount = articles.Count;
            response.CreateTime = DateTime.Now.Ticks;
            response.Articles = articles;

            return response;
        }
    }

大家可以看到,接口参数已经改成了MiddleMessage,这样就避免了原先我再new一个RequestMessage了, 直接用了MiddleMessage.RequestMessage。

CnBlogsFeed是一个自己写的采集类,目的是采集博客园首页数据,数字类型的构造函数,是一个提取数量,因为微信平台的限制,这个值必须在1-10之间。

因为是图文消息,而博客园呢只在Description中提供了用户的头像,而微信多图文消息会把第一篇文章的图片作为主图,大小为:320*200,所以我把第一张图片做成了默认图片,小图的话如果用户有头像就用用户的头像,如果没有则会显示一个默认小图,大小为:200*200。

看下CnBlogsFeed类,写的不好,将就看看吧:

public class CnBlogsFeed
    {
        private int m_topNum = 5;

        //缓存过期时间,这里是10分钟
        private static int s_timeout = 10 * 60 * 1000;
        //缓存过期时间
        private static DateTime s_outDate = DateTime.Now;
        //博客园文章列表正则表达式
        private static Regex s_cnblogsIndexRegex = new Regex("<div\\s*class=\"post_item\">\\s*.*\\s*.*\\s*.*\\s*.*\\s*.*\\s*.*\\s*.*\\s*<div\\s*class=\"post_item_body\">\\s*<h3><a\\s*class=\"titlelnk\"\\s*href=\"(?<href>.*)\"\\s*target=\"_blank\">(?<title>.*)</a>.*\\s*<p\\s*class=\"post_item_summary\">\\s*(?<content>.*)\\s*</p>");
        //内容中,用户头像正则表达式
        private static Regex s_picUrlRegex = new Regex("src=\"(?<picurl>.*)\"\\s");
        //博客园文章列表uri
        private static string s_cnblogsIndexUri = "http://www.cnblogs.com/mvc/AggSite/PostList.aspx?CategoryId=808&PageIndex=1";
        //默认的一个大图,一个小图的图片地址
        private static string s_defaultBigPicUri = "http://wx.jamesying.com/images/default_title.jpg";
        private static string s_defaultSmallPicUri = "http://wx.jamesying.com/images/default_small.jpg";

        //用来缓存请求过来的数据,不高兴用Cache了。
        private static List<Article> s_articles = null;

        public CnBlogsFeed(int topNum)
        {
            m_topNum = topNum;
        }

        public List<Article> GetTopCnblogsFeed()
        {
            if (s_articles == null)
            {
                GetTopCnblogsFeed(m_topNum);
            }
            else
            {
                if (DateTime.Now > s_outDate)
                {
                    GetTopCnblogsFeed(m_topNum);
                }
            }

            return s_articles;
        }

        private void GetTopCnblogsFeed(int m_topNum)
        {
            try
            {
                var html = GetRemoteUri(s_cnblogsIndexUri, Encoding.UTF8);
                var matchs = s_cnblogsIndexRegex.Matches(html);
                var i = 0;
                s_articles = new List<Article>();
                foreach (Match match in matchs)
                {
                    if (i >= m_topNum)
                        break;
                    var article = new Article
                    {
                        Title = match.Groups[2].Value,
                        Url = match.Groups[1].Value,
                        Description = match.Groups[3].Value
                    };

                    if (i == 0)
                    {
                        article.PicUrl = s_defaultBigPicUri;
                    }
                    else
                    {
                        var matchPic = s_picUrlRegex.Match(article.Description);
                        if (matchPic.Success)
                        {
                            article.PicUrl = matchPic.Groups[1].Value;
                        }
                        else
                        {
                            article.PicUrl = s_defaultSmallPicUri;
                        }
                    }

                    s_articles.Add(article);

                    i += 1;
                }

                s_outDate = DateTime.Now.AddMilliseconds(s_timeout);
            }
            catch(Exception ex)
            {
                s_articles = null;
                s_outDate = DateTime.Now;
#if DEBUG
                throw ex;
#endif
            }

            //return s_articles;
        }

        private string GetRemoteUri(string uri, Encoding encoding)
        {
            var client = new WebClient();
            client.Encoding = encoding;

            return client.DownloadString(uri);
        }
    }

基本工作完成,只要更改之前的TextMessageRole:

public IMessageHandler MessageRole(MiddleMessage msg)
        {
            var request = (RequestTextMessage)msg.RequestMessage;

            if (request.Content.IndexOf("博客园文章") > -1)
            {
                return new CnblogsArticleNewsMessageHandler();
            }

            if (request.Content.IndexOf("博客园") > -1)
            {
                return new CnblogsTextMessageHandler();
            }

            return new DefaultMessageHandler();
        }

这个规则简陋了点,之后会考虑下,打造一个文本命令的规范,因为Demo还不涉及到数据库,暂时都是手工判断。

接下来上传代码,测试一下:

输入博客园:

image

 

输入博客园文章:

image

 

 

测试完成,还能凑活用用,后续会用一个统一的文本命令方式,但有点纠结,不知道用什么方式,大家可以提供下意见。目前想到的是:

关键字+命令+参数(可选)

博客园+inday+5(博客园,用户为inday,前5文章)

天气+上海(获取上海今天的天气)

天气+上海+3(获取上海未来3天的天气)

后面会写一系列教程,尽量把常用的消息类型都用到。

PS:求职下吧,上海地区+电子商务类型公司,最好有旅游行业,职位的话无所谓,一个抬头而已,有发展前景,因本人30+了,不太想经常换工作了,薪资12k+就行,对于自我评价,还算是个负责的人,项目也好,学习也好,都会投入进去,对于C#比较精通点,也可以其他语言。需要的Email给我:james#taogame.com(#->@)

PS2:今天收到宝宝的台历了,哈,真嗲

相关文章
ly~
|
6天前
|
存储 供应链 小程序
除了微信小程序,PHP 还可以用于开发哪些类型的小程序?
除了微信小程序,PHP 还可用于开发多种类型的小程序,包括支付宝小程序、百度智能小程序、抖音小程序、企业内部小程序及行业特定小程序。在电商、生活服务、资讯、工具、娱乐、营销等领域,PHP 能有效管理商品信息、订单处理、支付接口、内容抓取、复杂计算、游戏数据、活动规则等多种业务。同时,在企业内部,PHP 可提升工作效率,实现审批流程、文件共享、生产计划等功能;在医疗和教育等行业,PHP 能管理患者信息、在线问诊、课程资源、成绩查询等重要数据。
ly~
38 6
|
6天前
|
小程序 JavaScript API
微信小程序开发学习之页面导航(声明式导航和编程式导航)
这篇文章介绍了微信小程序中页面导航的两种方式:声明式导航和编程式导航,包括如何导航到tabBar页面、非tabBar页面、后退导航,以及如何在导航过程中传递参数和获取传递的参数。
微信小程序开发学习之页面导航(声明式导航和编程式导航)
|
20天前
|
存储 移动开发 监控
微信支付开发避坑指南
【9月更文挑战第11天】在进行微信支付开发时,需遵循官方文档,确保权限和参数配置正确。开发中应注重安全,验证用户输入,合理安排接口调用顺序,并处理异常。上线后需实时监控支付状态,定期检查配置,关注安全更新,确保系统稳定运行。
|
26天前
|
移动开发 小程序 JavaScript
uni-app开发微信小程序
本文详细介绍如何使用 uni-app 开发微信小程序,涵盖需求分析、架构思路及实施方案。主要功能包括用户登录、商品列表展示、商品详情、购物车及订单管理。技术栈采用 uni-app、uView UI 和 RESTful API。文章通过具体示例代码展示了从初始化项目、配置全局样式到实现各页面组件及 API 接口的全过程,并提供了完整的文件结构和配置文件示例。此外,还介绍了微信授权登录及后端接口模拟方法,确保项目的稳定性和安全性。通过本教程,读者可快速掌握使用 uni-app 开发微信小程序的方法。
57 3
|
2月前
|
小程序
Taro@3.x+Vue@3.x+TS开发微信小程序,设置转发分享
本文介绍了Taro中`useShareAppMessage`的使用方法,需在页面配置`enableShareAppMessage: true`并重新编译。
Taro@3.x+Vue@3.x+TS开发微信小程序,设置转发分享
|
2月前
|
小程序 数据安全/隐私保护
Taro@3.x+Vue@3.x+TS开发微信小程序,网络请求封装
在 `src/http` 目录下创建 `request.ts` 文件,并配置 Taro 的网络请求方法 `Taro.request`,支持多种 HTTP 方法并处理数据加密。
Taro@3.x+Vue@3.x+TS开发微信小程序,网络请求封装
|
2月前
|
小程序
Taro@3.x+Vue@3.x+TS开发微信小程序,上传文件
本文介绍如何在Taro项目中使用Nut UI的`&lt;nut-uploader/&gt;`组件实现图片上传功能,并通过示例代码展示了自定义上传逻辑的方法。
Taro@3.x+Vue@3.x+TS开发微信小程序,上传文件
|
2月前
|
小程序 JavaScript Java
微信小程序的后端开发需要使用什么语言?
【8月更文挑战第22天】微信小程序的后端开发需要使用什么语言?
311 65
|
2月前
|
小程序 JavaScript
Taro@3.x+Vue@3.x+TS开发微信小程序,使用轮播图
本文介绍了使用 Taro 和 Vue 创建轮播组件的两种方法:一是通过 `&lt;swiper&gt;` 实现,二是利用 Nut UI 的 `&lt;nut-swiper&gt;` 组件实现。
Taro@3.x+Vue@3.x+TS开发微信小程序,使用轮播图
|
2月前
|
小程序
Taro@3.x+Vue@3.x+TS开发微信小程序,根据系统主题展示不同样式(darkMode)
本文介绍如何在Taro项目中配置深色模式。通过在`src/app.config.ts`设置`darkmode`选项和在`theme.json`中定义主题变量,可以实现跟随系统主题的界面风格切换。
Taro@3.x+Vue@3.x+TS开发微信小程序,根据系统主题展示不同样式(darkMode)

热门文章

最新文章

下一篇
无影云桌面