瘦人说

LINQ To Weibo

介绍个新浪微博的查询实现,LINQ To Weibo,属于Mr开发范围之内,我取了很骚包的名字,Mr.LinqToWeibo。

很早就用C#实现了OAuth 1.0(不过现在2.0都出了,正在做2.0版本的实现),也一直想把微博的获取变得简便,不用传统的api封装,我选择了LINQ,只为调用者利用LINQ语法,让代码更加语义化。(前端过敏,语义化居然用到这里)。

LINQ To Weibo支持的新浪微博API:

微博查询

  • PUBLIC_TIMELINE,获取最新的公共微博消息,
  • FRIENDS_TIMELINE,获取当前登录用户及其所关注用户的最新微博消息
  • USER_TIMELINE,获取用户发布的微博消息列表
  • MENTIONS,获取@当前用户的微博列表
  • REPOST_TIMELINE,返回一条原创微博的最新n条转发微博信息
  • REPOST_BY_ME,返回用户转发的最新n条微博信息
  • WEIBO_FOR_ONE_TRENDS,获取某一话题下的微博

评论查询

  • COMMENTS_TIMELINE,获取当前用户发送及收到的评论列表
  • COMMENTS_BY_ME,获取当前用户发出的评论
  • COMMENTS_TO_ME,获取当前用户收到的评论,
  • COMMENTS_FOR_ONE_WEIBO,根据微博消息ID返回某条微博消息的评论列表

这些API的实现主要是微博对象和评论对象的获取,对于查询来说,应该够用了。现在我简单说下库的调用。

调用准备

整个调用过程很简单,创建一个查询对象

IQueryableWeiboData<Weibo> data = new QueryableWeiboData<Weibo>();

当然,如果你想查询评论的话,泛型参数传 Comment。接着需要导入用户的accessToken和accessTokenSecret来源于OAuth1.0,设置调用方法:

data.SetAccessTokenAndSecret(
       "2b86af73326d980864d27",  // accessToken
       "bee7898872f88095a151d"); // accessTokenSecret

除了创建查询对象和载入用户token之外,还需要指定查询API是什么,我把它定义为域Scope。Scope是枚举类型,指就是之前列出的API的值。设置Scope的值,调用

data.SetWeiBoScope (Scope.WEIBO_FOR_ONE_TRENDS);

现在就可以很爽的查询了。举两个例子。

FRIENDS_TIMELINE

获取当前登录用户及其所关注用户的最新微博消息,整个查询是所有微博程序都有了,看用了LINQ语法的调用。

data.Where (weibo => weibo.Id > 3100000).Skip(1).Take(20);

意思是查询微博对象的id大于3100000的微博,并且取分页信息:第2页(Skip(1)本来是指调用一条记录,为了语义更完善,我暂时用Skip代表跳过的页数),每页取20条。

data.Where (weibo => weibo.Id > 3100000 && weibo.Feature == Feature.PIC)

意思是查询微博对象的id大于3100000,类型是含有图片的微博,分也方式是默认(如下)。

如果不设置Skip和Take的话,默认是第一页的20条。那时你也可以这么写:

from weibo in data where weibo.Id > 3100000 select weibo;

from weibo in data
where weibo.Id > 3100000 && weibo.Feature == Feature.PIC
select weibo;

看上去感觉都很棒。另外,我实现的是IQueryable<T>接口,所有的查询都会延迟到便利的时候。

COMMENTS_FOR_ONE_WEIBO

很多时候,会根据指定微博查询其评论,此时就应该用到COMMENTS_FOR_ONE_WEIBO API,首先我们创建查询的上下文对象和设置查询的API。

var comments = new QueryableWeiboData<Comment>();
comments.SetWeiBoScope (Scope.COMMENTS_FOR_ONE_WEIBO);

完成之后,Code查询表达式查询ID为3100000的微博的前五条评论:

comments.Where (cmt => cmt.Weibo.Id == 3100000).Take(5)

如果在写程序时不知道确切ID,先得到微博对象weibo,那么可以这么写:

comments.Where (cmt => cmt.Weibo.Id == weibo.Id).Take(5)

所有API的调用规则都和上面两个例子一样,在这里我列出新浪微博API文档上出现的字段和调用方式:

  1. since_id 和 max_id 可以通过lambda表达式中weibo.Id的大于小于操作完成
  2. count 通过Take方法
  3. page 通过Skip方法,注意Skip(1)代表跳过一页,指第二页
  4. base_app 和 feature 可以利用weibo.Feature 和 weibo.BaseApp设置查询条件。这两个字段很特殊,因为新浪API不给力,在微博对象上找不到对应字段,get方法也就失去了意义,如果你调用get方法获取它的值,会抛出NotSupportedException,希望有一天能改进。
  5. id 字段,此字段有多种意思,这个完全是新浪设计API时不给力,混乱。
    表示微博对象的Id,用weibo.Id
    表示微博对象上发微博者得Id,可以用weibo.User.Id
    表示评论上发评论者得Id,可以用comment.User.Id
  6. user_id 和 screen_name,此两个字段设计的更加傻逼,在文档中说明这两个字段主要是用来区分用户ID跟微博昵称,然后调用方式是REST方式,表面上Id必填,但是文档里面又说Id不必填。。。那我怎么办,所以不支持,如果要查询USER_TIMELINE API,请使用weibo.User.Id,指定特定的Int64类型Id值。
  7. trend_name,代表话题的名称,可以使用weibo.Trend.KeyWord,此字段依旧是个鸡肋,和之前的feature和base_app如出一辙,在查询返回的微博对象上没有“话题”这一字段,所以此字段的实现只是用于查询,千万别在查询出来的结果集中访问weibo.Trend,因为它总是抛出NotSupportedException,这个是我不希望出现的,可悲。

希望大家喜欢Mr.LinqToWeibo,如果想要看代码的话,可以联系我,暂时不提供下载,不是怕大家笑话代码如何差,而是还有一些关于我自己的token,我申请的app的consumerKey和consumerSecret的东西没有像到好的方法和代码分离起来,想到了之后就会让大家down下来看看,给点意见。

目前发现需要改进或者缺少的功能有:

  1. 非表达式的支持,目前只支持weibo.BaseApp == false / true,而不是!weibo.BaseApp
  2. 或关系支持,目前在Where方法里面只支持逻辑与&&关系,甚至还需要考虑括号()优先级的问题,这个目前还没有好的解决方案,新浪的API貌似也还不支持这种方式。而且参数只支持 == 等于操作,如果是微博的ID还支持 >= 或 <= 操作。
  3. 二次过滤的实现,二次过滤指API查询条件之外的过滤,主要是利用LinqToObject方式实现,如果开启二次过滤,分页信息将会不准确

 

Comments

Proudly published with Hexo