统计个人博客园文章数据(WPF4 版)
2010-04-21 08:42
411 查看
每当需要整理博客文章数据时总感觉很繁琐。虽然有许多功能强大的统计工具(例如,谷歌分析),但是仅限于加载该工具时至今的数据。对于早期未加入统计范围的博文来说就显得很不准确了。博客园管理页面中虽然也有博文详细信息,但要提取出来也很麻烦,总不能每页复制->粘贴到Excel 吧。
看了老赵一篇关于 《按月统计博客园单个用户的发文数量》的文章后,于是决定也从“随笔档案”下手做一个自动抓取博文信息的工具,欢迎大家多多交流探讨!
看到这些代码后心中有稍许安慰。在<div class="entrylistPosttitle">中有我想要的博文“标题”和“链接地址”数据,在<div class="entrylistItemPostDesc">中有博文的“阅读量”和“评论量”。注,以上HTML 代码不一定实用所有博客园主题,大家可按各自主题设置自行调整正则表达式对比模式,接下来要做的就是将这些数据提取出来。
创建一个Article 类保存博文相关数据:
通过正则表达式比对,获取“标题”、“链接”、“阅读量”、“评论量”数据,并存入blogInfo 中:
最后,通过一个Button 事件触发以上方法,其中比较费事的就是正则表达式的定义regexPattern,将所有取到的数据与DataGrid 列表进行Binding。
数据的抓取速度取决于随笔档案的数量和当时的网速。有时我这里上博客园很慢,那就别指望取到数据了。以下是软件截图,其中还添加了将数据导出Excel 的功能。
2. WPF 4 DataGrid 控件(基本功能篇)
3. WPF 4 DataGrid 控件(自定义样式篇)
4. WPF 4 DataGrid 控件(进阶篇一)
看了老赵一篇关于 《按月统计博客园单个用户的发文数量》的文章后,于是决定也从“随笔档案”下手做一个自动抓取博文信息的工具,欢迎大家多多交流探讨!
工作原理
博客园的随笔档案是按每月博文进行归总的页面,例如“http://www.cnblogs.com/gnielee/archive/2010/04.html” 会列出我在2010年4月写过的所有文章。浏览该页面的HTML 代码会看到类似下面的代码片段(代码格式在本文中调整过)。<div class="entrylistPosttitle"> <a id="ArchiveMonth1_Days_Entries_ctl00_TitleUrl" class="entrylistItemTitle" href="http://www.cnblogs.com/gnielee/archive/2010/04/17/microsoft-research-rex-tool.html"> Microsoft Rex 正则表达式工具</a> </div> <div class="entrylistPostSummary"> 摘要: <img src="http://images.cnblogs.com/cnblogs_com/gnielee/200730/o_channel9.jpg" class="desc_img"/> 这里都是摘要内容… … <a href='http://www.cnblogs.com/gnielee/archive/2010/04/17/microsoft-research-rex-tool.html'>阅读全文</a></div> <div class="entrylistItemPostDesc"> posted @ <a href=http://www.cnblogs.com/gnielee/archive/2010/04/17/microsoft-research-rex-tool.html Title = "permalink">2010-04-17 09:42</a> Gnie 阅读(1574) | <a href=http://www.cnblogs.com/gnielee/archive/2010/04/17/microsoft-research-rex-tool.html#FeedBack Title = "comments, pingbacks, trackbacks">评论 (35)</a> <a href="http://www.cnblogs.com/gnielee/admin/EditPosts.aspx?postid=1714077">编辑</a> </div>
看到这些代码后心中有稍许安慰。在<div class="entrylistPosttitle">中有我想要的博文“标题”和“链接地址”数据,在<div class="entrylistItemPostDesc">中有博文的“阅读量”和“评论量”。注,以上HTML 代码不一定实用所有博客园主题,大家可按各自主题设置自行调整正则表达式对比模式,接下来要做的就是将这些数据提取出来。
整理HTML 数据
首先通过WebClient 按月获取到随笔档案的HTML 代码,并针对标题中的一些特殊字符串(例如,&)进行替换:private string GetHtmlCode(string strUid, string strMonth) { WebClient client = new WebClient(); client.Encoding = Encoding.GetEncoding("UTF-8"); string url = String.Format("http://www.cnblogs.com/{0}/archive/{1}.html", strUid, strMonth); string htmlCode = client.DownloadString(url); htmlCode = htmlCode.Replace("&", "&"); htmlCode = htmlCode.Replace("<", "<"); htmlCode = htmlCode.Replace(">", ">"); return htmlCode; }
创建一个Article 类保存博文相关数据:
public class Article { public string Title { get; set; } public Uri Url { get; set; } public int Read { get; set; } public int Comment { get; set; } }
通过正则表达式比对,获取“标题”、“链接”、“阅读量”、“评论量”数据,并存入blogInfo 中:
ObservableCollection<Article> blogInfo = new ObservableCollection<Article>(); private void GetBlogData(string strDate, string strPattern) { MatchCollection matchCollection = Regex.Matches(GetHtmlCode(urlText.Text.Trim(), strDate), strPattern, RegexOptions.IgnoreCase); foreach (Match match in matchCollection) { blogInfo.Add(new Article() { Title = match.Groups["title"].Value.Trim(), Url = new Uri(match.Groups["address"].Value.Trim()), Read = Convert.ToInt32(match.Groups["read"].Value.Trim()), Comment = Convert.ToInt32(match.Groups["comment"].Value.Trim()) }); } }
最后,通过一个Button 事件触发以上方法,其中比较费事的就是正则表达式的定义regexPattern,将所有取到的数据与DataGrid 列表进行Binding。
private void goBtn_Click(object sender, RoutedEventArgs e) { blogInfo.Clear(); DateTime fromDate = Convert.ToDateTime(fromDatePicker.Text.Trim()); DateTime toDate = Convert.ToDateTime(toDatePicker.Text.Trim()).Add(new TimeSpan(30, 0, 0, 0)); if (toDate < fromDate) { MessageBox.Show("ToDate can't earlier than FromDate"); } else { string datePattern; string regexPattern = @"<div class=""entrylistPosttitle""><a id=""[\w]+"" class=""entrylistItemTitle"" href=""(?<address>\S+)"">(?<title>[\x00-\xff\S]+?)</a></div>[\S\s]+?" + @"<div class=""entrylistItemPostDesc"">[\S\s]+?\((?<read>\d+)\)[\S\s]+?\((?<comment>\d+)\)"; while (fromDate <= toDate) { datePattern = fromDate.ToString("yyyy/MM"); GetBlogData(datePattern, regexPattern); fromDate = fromDate.Add(new TimeSpan(30, 0, 0, 0)); } int readCount = 0, commentCount = 0; foreach (Article blogList in blogInfo) { readCount += blogList.Read; commentCount += blogList.Comment; } sumLabel.Content = String.Format("Article: {0} Read: {1} Comment: {2}", blogInfo.Count.ToString(),readCount.ToString(),commentCount.ToString()); dataGrid.DataContext = blogInfo; } }
数据的抓取速度取决于随笔档案的数量和当时的网速。有时我这里上博客园很慢,那就别指望取到数据了。以下是软件截图,其中还添加了将数据导出Excel 的功能。
相关参考
1. .NET Framework 4 Regular Expression Language Elements2. WPF 4 DataGrid 控件(基本功能篇)
3. WPF 4 DataGrid 控件(自定义样式篇)
4. WPF 4 DataGrid 控件(进阶篇一)
源码下载
软件本身主要涉及WPF4 的两个新控件:DatePicker、DataGrid,感兴趣的朋友可以下载源代码研究,或者再加以完善,欢迎大家拍砖交流。相关文章推荐
- 统计个人博客园文章数据(WPF4 版)
- 博客园如何统计个人博客的访问量
- 【数据分析】6 点发的文章在博客园阅读量最高?
- csdn个人博客流量统计方法的构想和实施(基本数据能看到了)
- (个人项目)英语文章词频统计
- 关系型数据库工作原理-数据特征统计分析(翻译自Coding-Geek文章)
- Python网络爬虫(3)- 统计个人CSDN的文章信息
- 统计个人CSDN的博客文章数量
- c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程
- 自定义博客园,个性导航二级下拉菜单,访客统计,侧边栏分享,文章目录自动生成,全局/文章返回顶部
- 本人大多数文章发表在博客园,以及个人博客上
- 游戏数据统计:【ID:村里最强】个人高速道具赛统计图表
- oracle 备份还原数据库,及数据导入导出的文章地址,个人经验总结
- WPF中的数据模板(DataTemplate)(引用别人的文章 )
- WPF学习日志1---DataGrid绑定与修改更新(数据List & 数据库)[部分代码有摘录其他文章]
- 2016年KDD IJCAI WWW ICDM 文章的个人统计
- 博客园 一些个人认为挺不错的文章
- 查询登录日志中,某个人最新的一 条数据,或者作者发的最新的一篇文章,group by中最新的一条数据
- hexo+github打造个人博客系列之数据统计与分析
- 数据统计的重要性