UWP 获取博客园积分,并以图标形式呈现变化趋势

Posted hupo376787

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UWP 获取博客园积分,并以图标形式呈现变化趋势相关的知识,希望对你有一定的参考价值。

先看一下效果吧

技术图片

 

 

1. 分析

说实话,之前还真没在乎过博客园的排名和积分,博客园默认也不给显示。需要自己到选项里面勾选才可以。

技术图片

 

 之前也有几个大佬写过类似的文章,不过是很早了。博客园关于获取积分的api已经变了。

也不算是api吧,毕竟不是官方公开的。不过自己可以通过查看页面元素,找到博客园的积分url。

 

在你勾选?了上面的选项之后,打开你的博客主页,比如我的就是https://www.cnblogs.com/hupo376787/

按F12,调出开发者工具,进入Network选项卡。

如果在下面的列表里面没有数据,F5刷新一下页面即可。

技术图片

 

 

然后,点击【sidecolumn.aspx】,右侧就会出现相信的信息。

右击【sidecolumn.aspx】,【copy link address】,这个url就是我们要找的。

然后根据这个url返回的信息,我们利用正则表达式或者其他手段找到积分和排名的数据即可。

 

2. 写Xaml界面

既然根据上面的分析,可以拿到积分和排名的数据,那么写代码就简单多了。

我这里使用C#来写的,语言只是一种工具,你也可以用Java、Swift、javascript、Flutter等,还可以用Python写。

无论哪一种,只要能拿到数据,用图表展示出来即可。

在xaml中,定义一下用户名输入框,还有一个图表控件。

图表使用的Microcharts。这是一个开源的图表控件,Github上已经斩获1000多个??????????

<StackPanel>
            <TextBox 
                x:Name="textBlockUser" 
                Background="Transparent"
                Padding="0, 5"
                BorderThickness="0"
                Width="200"
                HorizontalAlignment="Left"
                PlaceholderText="hupo376787"
                TextChanged="User_TextChanged"/>
            <TextBlock x:Name="textBlockDate"/>
            <TextBlock x:Name="textBlockScore"/>
            <TextBlock x:Name="textBlockRank"/>

            <charts:ChartView x:Name="microChart"
                              Height="300"/>
        </StackPanel>

 

3. 获取网页数据

利用HttpClient写代码,获取指定url的网页源代码。

user是文本框可以输入的用户id。

然后根据Http返回来的数据,做成一个List<string>。这样就不用写正则表达式查找??了。

其实主要是我不大会写正则表达式而已。技术图片

 不好意思暴露了。

 

 string url = "https://www.cnblogs.com/" + user + "/ajax/sidecolumn.aspx";
                HttpClient client = new HttpClient();
                HttpResponseMessage message = await client.GetAsync(url);
                string content = await message.Content.ReadAsStringAsync();
                List<string> lines = content.Replace("积分与排名", "").Split("
").ToList();

                var scoreHeaderIndex = lines.FindIndex(x => x.Contains("积分"));
                var rankHeaderIndex = lines.FindIndex(x => x.Contains("排名"));

                int score = Convert.ToInt32(lines[scoreHeaderIndex + 1]);
                int rank = Convert.ToInt32(lines[rankHeaderIndex + 1]);

 

 

4. 生成图表

因为要做成趋势图,并且博客园返回的数据只是当天的信息,并不不包含历史记录。

所以需要手动记录数据,并存放在本地。

之前那几个大佬也是这样子,写成了python或者js,每天自动运行一次,保存数据。

UWP想要记录数据,需要一点额外的权限。

因为需要记录txt文件,而这样的文本文件最好放在user/document文件夹下。

首先,用记事本打开Package.appxmanifest,加上

<Capabilities>
   <uap:Capability Name="documentsLibrary" />
</Capabilities>

 

然后在vs中打开Package.appxmanifest,添加声明。按照图示设置。

技术图片

 

这样就有权限写入txt到文档文件夹了。

                StorageFolder storageFolder = KnownFolders.DocumentsLibrary;
                StorageFile file = await storageFolder.CreateFileAsync("cnBlogs.txt", CreationCollisionOption.OpenIfExists);
                string existData = await FileIO.ReadTextAsync(file);
                List<string> list = existData.Split("
").ToList();

 

我这儿首先读取了txt里面的数据,如果这个txt不存在,就创建。已经存在的话,直接打开读取数据。

然后绘图

                Random rnd = new Random();
                List<ChartEntry> entries = new List<ChartEntry>();
                foreach(var item in list)
                {
                    if (item.Trim() == "")
                        continue;

                    var singleLineArray = item.Split(",");
                    var entry = new ChartEntry((float)Convert.ToDouble(singleLineArray[1]))
                    {
                        Label = singleLineArray[0],
                        ValueLabel = singleLineArray[1],
                        Color = SKColor.Parse(String.Format("#{0:X6}", rnd.Next(0x1000000)))
                    };
                    entries.Add(entry);
                }var chart = new LineChart {
                    Entries = entries,
                    MinValue = 100000,
                    BackgroundColor = SKColors.Transparent
                };
                this.microChart.Chart = chart;

 

如果在生成折线图的时候,不加上

BackgroundColor = SKColors.Transparent

生成的图表默认白色。但是背景透明好看。

 

 

5. 记录获取的积分和排名数据

 为了防止一天内多次打开app,重复记录,所以我做了一个检查。

利用System.IO写入数据。

                string contentToWrite = "";
                //Add Today
                if (!existData.Contains(DateTime.Now.ToString("yyyy-MM-dd")))
                {
                    var entryToday = new ChartEntry((float)Convert.ToDouble(score))
                    {
                        Label = score.ToString(),
                        ValueLabel = DateTime.Now.ToString("yyyy-MM-dd"),
                        Color = SKColor.Parse(string.Format("#{0:X6}", rnd.Next(0x1000000)))
                    };
                    entries.Append(entryToday);

                    contentToWrite = existData + "
" + DateTime.Now.ToString("yyyy-MM-dd") + "," + score + "," + rank;
                }
                else
                    contentToWrite = existData;

                //Write
                await FileIO.WriteTextAsync(file, contentToWrite);

 

 

6. 完成的代码

        private async Task GetData(string user)
        {
            try
            {
                string url = "https://www.cnblogs.com/" + user + "/ajax/sidecolumn.aspx";
                HttpClient client = new HttpClient();
                HttpResponseMessage message = await client.GetAsync(url);
                string content = await message.Content.ReadAsStringAsync();
                List<string> lines = content.Replace("积分与排名", "").Split("
").ToList();

                var scoreHeaderIndex = lines.FindIndex(x => x.Contains("积分"));
                var rankHeaderIndex = lines.FindIndex(x => x.Contains("排名"));

                int score = Convert.ToInt32(lines[scoreHeaderIndex + 1]);
                int rank = Convert.ToInt32(lines[rankHeaderIndex + 1]);

                textBlockDate.Text = DateTime.Now.ToString("yyyy-MM-dd");
                textBlockScore.Text = score.ToString();
                textBlockRank.Text = rank.ToString();

                StorageFolder storageFolder = KnownFolders.DocumentsLibrary;
                StorageFile file = await storageFolder.CreateFileAsync("cnBlogs.txt", CreationCollisionOption.OpenIfExists);
                string existData = await FileIO.ReadTextAsync(file);
                List<string> list = existData.Split("
").ToList();

                Random rnd = new Random();
                List<ChartEntry> entries = new List<ChartEntry>();
                foreach(var item in list)
                {
                    if (item.Trim() == "")
                        continue;

                    var singleLineArray = item.Split(",");
                    var entry = new ChartEntry((float)Convert.ToDouble(singleLineArray[1]))
                    {
                        Label = singleLineArray[0],
                        ValueLabel = singleLineArray[1],
                        Color = SKColor.Parse(String.Format("#{0:X6}", rnd.Next(0x1000000)))
                    };
                    entries.Add(entry);
                }

                string contentToWrite = "";
                //Add Today
                if (!existData.Contains(DateTime.Now.ToString("yyyy-MM-dd")))
                {
                    var entryToday = new ChartEntry((float)Convert.ToDouble(score))
                    {
                        Label = score.ToString(),
                        ValueLabel = DateTime.Now.ToString("yyyy-MM-dd"),
                        Color = SKColor.Parse(string.Format("#{0:X6}", rnd.Next(0x1000000)))
                    };
                    entries.Append(entryToday);

                    contentToWrite = existData + "
" + DateTime.Now.ToString("yyyy-MM-dd") + "," + score + "," + rank;
                }
                else
                    contentToWrite = existData;

                var chart = new LineChart {
                    Entries = entries,
                    MinValue = 100000,
                    BackgroundColor = SKColors.Transparent
                };
                this.microChart.Chart = chart;

                //Write
                await FileIO.WriteTextAsync(file, contentToWrite);
            }
            catch
            {

            }
        }

 

之所以加了try{ ... } catch{ ... },是因为在输入用户名的时候,可以根据文本变化,实时检测是不是有效的用户,并生成图表。

 

7. 总结

获取并显示数据,本身不是一件很难的事情,关键是怎么利用得到的数据,并把它很有的呈现出来。

当然,我这里也少做了一步,就是让应用自启动,开机的时候获取一次数据,这样就可以防止某天忘记打开,导致数据断层的问题了。

关于uwp如何随开机启动,我还没研究过,以后有时间的写一些分享心得。

 

OK,Merry Christmas!Lonely Christians!

??????????????????????????????????????

??????????????????????

????????????????????????????????????????????

??????????????????????????????????????

????????????????????????????????????????

 ????????????????????????????????????????

 

以上是关于UWP 获取博客园积分,并以图标形式呈现变化趋势的主要内容,如果未能解决你的问题,请参考以下文章

博客园积分与排名升级攻略(转)

微积分小课堂:积分(从微观趋势了解宏观变化)

微积分小课堂:微分(从宏观变化了解微观趋势)

找人做LOGO设计代人做商标设计代人做企业公司品牌标志图标找人做创意名片设计

cnblogs博客园修改网站图标icon

UWP开发-自适应布局