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

先看一下效果吧python

 

 

1. 分析ajax

说实话,以前还真没在意过博客园的排名和积分,博客园默认也不给显示。须要本身到选项里面勾选才能够。正则表达式

 

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

也不算是api吧,毕竟不是官方公开的。不过本身能够经过查看页面元素,找到博客园的积分url。app

 

在你勾选✔了上面的选项以后,打开你的博客主页,好比个人就是https://www.cnblogs.com/hupo376787/dom

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

若是在下面的列表里面没有数据,F5刷新一下页面便可。ide

 

 

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

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

而后根据这个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("\n").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("\r\n").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 + "\r\n" + 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("\n").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("\r\n").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 + "\r\n" + 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!

❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️

⛄⛄⛄⛄⛄⛄⛄⛄⛄⛄⛄⛄⛄⛄⛄⛄⛄⛄⛄⛄⛄⛄

🎄🎄🎄🎄🎄🎄🎄🎄🎄🎄🎄🎄🎄🎄🎄🎄🎄🎄🎄🎄🎄🎄

🎅🎅🎅🎅🎅🎅🎅🎅🎅🎅🎅🎅🎅🎅🎅🎅🎅🎅🎅

🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎

 🧦🧦🧦🧦🧦🧦🧦🧦🧦🧦🧦🧦🧦🧦🧦🧦🧦🧦🧦🧦

相关文章
相关标签/搜索