前几天做个调用新浪API的WPF程序,因为statuses/repost_timeline接口只能返回最新的2K条数据(事实上,我测试的时候,只能读出1986条数据,有大牛知道怎么回事吗?),这对于一个稍微‘火’一点的新浪微博的转发统计工作根本不能满足,所以这几天小生一直苦思解决办法,比较可行的我觉得应该是实时的监控这条微博,定时监控,不断更新统计出了来的数据。(因为我觉得应用中心那边的统计工具,应该也是后台自动运行统计的。)
小生的思路也许并不清晰,也许实现起来的方式有点过于繁琐了。(-.-)
具体思路如下:
除了保留原本查询所用到的一些公共控件,还要添加几个控件,原因是:
界面部分:
class="code_img_closed" src="/Upload/Images/2013081415/0015B68B3C38AA5B.gif" alt="" />logs_code_hide('b7c46b8c-1f89-4e3a-bee5-064f80443b64',event)" src="/Upload/Images/2013081415/2B1B950FA3DF188F.gif" alt="" /><Window x:Class="sina_Client.MonitorWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="微博转发监控" Height="550" Width="650" Closed="Window_Closed_1"> <Grid> <Menu HorizontalAlignment="Left" Height="28" VerticalAlignment="Top" Width="654"> <MenuItem Header="用户"> <MenuItem Name="m1" Header="注销" Click="m1_Click_1"></MenuItem> <MenuItem Name="m2" Header="退出" Click="m2_Click_1"></MenuItem> </MenuItem> <MenuItem Header="工具"> <MenuItem Name="m3" Header="抽奖" Click="m3_Click_1"></MenuItem> <MenuItem Name="m4" Header="微博统计" Click="m4_Click_1"></MenuItem> </MenuItem> </Menu> <Label Content="填入要查询的微博ID:(单条)" HorizontalAlignment="Left" Margin="10,35,0,0" VerticalAlignment="Top"/> <TextBox Name="txtID" HorizontalAlignment="Left" Height="23" Margin="10,66,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="373" MaxLength="500"/> <Label Content="刷新间隔时间(分钟):" HorizontalAlignment="Left" Margin="10,94,0,0" VerticalAlignment="Top"/> <TextBox Name="txtTime" HorizontalAlignment="Left" Height="23" Margin="157,96,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="58"/> <Label Content="运行时间(小时):" HorizontalAlignment="Left" Margin="240,94,0,0" VerticalAlignment="Top"/> <TextBox Name="txtHours" HorizontalAlignment="Left" Height="23" Margin="363,96,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="50"/> <Button Name="btnStart" Content="运 行" HorizontalAlignment="Left" Margin="448,67,0,0" VerticalAlignment="Top" Width="75" Height="52" Click="btnStart_Click"/> <RichTextBox Name="rtText" HorizontalAlignment="Left" Height="385" Margin="10,125,0,0" VerticalAlignment="Top" Width="622"> <FlowDocument> <Paragraph> <Run Text=""/> </Paragraph> </FlowDocument> </RichTextBox> </Grid> </Window>View Code
接下来代码部分。
时间的控制方面,我引用了System.Windows.Threading的DispatcherTimer类。统计的方式,之前想了很多方法,一个是记录之前一次统计的最后一条记录的id和created_at两个字段(用last和lastcreated_at两个字段来记录),在下一次统计的时候,去判断当前记录的字段是否和last和lastcreated_at两个字段记录的值一致,一致则说明上次记录到这个记录,所以我只取这个记录之前的那几条;另外一个,我每次统计当前记录的条数,比如,第一次我记录150条数据,那么我第二次统计的时候发现一共有200条数据,那么我通两个int变量,得到两次记录的差值,从而限制我读取的条数。思考了很久,我还觉得第二个方法比较好实现,但不管用哪个方法,都要保证我每次读取记录的时候,都不超过2K条数据。
运行的按钮代码:
if (this.txtID.Text == "") { MessageBox.Show("这ID有问题吧", "凸(_-#)"); return; } if (this.txtTime.Text == "") { MessageBox.Show("需要设置一个刷新时间", "凸(_-#)"); return; } if (this.txtHours.Text == "") { MessageBox.Show("需要设置一个运行时间", "凸(_-#)"); return; } sb = new StringBuilder(); sb.Append("The MonitorWindow is Runing....\n"); id = _sina.API.Entity.Statuses.QueryID(1, false, true, this.txtID.Text); sb.Append("\nThe message ID:" + id); RText(sb.ToString()); dt = new DispatcherTimer(); dt.Interval = new TimeSpan(int.Parse(this.txtTime.Text) / 60, int.Parse(this.txtTime.Text) % 60, 0); endtime = DateTime.Now.AddHours(int.Parse(this.txtHours.Text)); dt.Tick += MonitorWeibo; dt.Start();
监控事件代码:
DateTime t = DateTime.Now; if (t > endtime) { dt.Stop(); } try { string[] Rname; int x = _sina.API.Entity.Statuses.RepostTimeline(id).TotalNumber; if (num == 0) { Rname = new string[x]; oldcount = x; } else { count = x; if (count - oldcount > 0) { x = count - oldcount; Rname = new string[x]; oldcount = count; } else if (count - oldcount == 0) { Rname = new string[1]; num++; sb.Append("\n Number of times:" + num + ",Reposts Count:" + c); RText(sb.ToString()); c = 0; return; } else { Rname = new string[x]; } } //Statuses.RepostTimeline接口默认读取50条数据,此处读取20条 //如果数据大于20条,则进行分批读取 if (x > 20) { for (int i = 1; i <= x / 20 + 1; i++) { if (i > 100) { break; } var _msgInfo = _sina.API.Entity.Statuses.RepostTimeline(id, "0", "0", 20, i, 0); var jObject = JObject.Parse(_msgInfo.ToString()); int n; for (n = 0; n < _msgInfo.Statuses.Count(); n++) { sb.Append("\n Reposts User:" + jObject["reposts"][n]["user"]["name"]); Rname[m] = jObject["reposts"][n]["user"]["name"].ToString(); m++; c++; } } num++; sb.Append("\n Number of times:" + num + ",Reposts Count:" + c); c = 0; } else { var _msgInfos = _sina.API.Entity.Statuses.RepostTimeline(id, "0", "0", 20, 1, 0); var jObjects = JObject.Parse(_msgInfos.ToString()); int n; for (n = 0; n < _msgInfos.Statuses.Count(); n++) { if (x == n) { break; } sb.Append("\n Reposts User:" + jObjects["reposts"][n]["user"]["name"]); Rname[n] = jObjects["reposts"][n]["user"]["name"].ToString(); c++; } num++; sb.Append("\n Number of times:" + num + ",Reposts Count:" + c); c = 0; } RText(sb.ToString()); } catch (WeiboException ex) { MessageBox.Show(ex.Message); }
设置的一个小时没运行满,上午快下班了没时间。下午测试,再把结果补上来。如果结果没错,那再把每次读取的记录一直添加到excel文件里就好了。
ps:我觉得统计时,读取到的数据存在误差可能出现在转发的人把数据删除了,找个机会试试~