采集博客园文章,用瀑布流+无限滚动展示(附源码)

一 前言

  前段时间一直在了解关于Http相关的知识,然后园子里时不时有园友发关于采集网页信息的文章,然后自己也想试试如何做网页的数据采集,便开始在网找查找相关资料,

方法有很多种,如 用开源的框架忘了叫什么名了,或者用.net Framework自带的HttpwebRequest对象与HttpwebResponse对象,当然也还有其它对象也可以做到如 WebClient 等,而我选择用HttpwebRequest 与HttpWebResponse来处理。

  经过几个晚上的不断折腾终于把这东西折腾出来了,我的定位就只是用来练手所以不免会有BUG,这个小工具有两个BUG 一个在无限滚动这里,都以经按插件的参数配置了,可它就是不听使唤,老是会自动触发加载事件,不得以我来个限定最多只加载10页的数据。如果有熟悉这个插件的朋友,下载源码后帮忙修改下,我拿它真没折了.......先谢过了~~

第二个BUG在构造Http请求时有时正常,有时却出现请求超时 比如我在家里测试时,都可以正常运行,而同样的代码放到公司时却出现请求超时,这个问题真心不知道是什么原因引起的,

这是我写的第二个小工具

第一个在这里  文件夹管理工具(MVC+zTree+layer)(附源码)

本项目地址在这里  采集博客园文章工具

文章还涉及到正则表达示,我总结了一篇相关的文章

在这里 读懂正则表达式就这么简单

 

 

二 工具介绍与思路介绍

 

2.1工具截图

效果大至就是这样了,样式什么的就没细调了,大伙将就下吧,能看就行了,主要这段时间比较忙,所以匆匆收尾了,还望见谅

 

2.2 工具所用到插件

  masonry:

  是 一款非常强大的jQuery动态网格布局插件,可以帮助开发人员快速开发类似剪贴画的界面效果。和CSS中float的效果不太一样的地方在 于,float先水平排列,然后再垂直排列,使用Masonry则垂直排列元素,然后将下一个元素放置到网格中的下一个开发区域。这种效果可以最小化处理 不同高度的元素在垂直方向的间隙

 

  infinitescroll

  是一个无限循环滚动的插件,做自动分页加载是很好用的,再配合masonry 瀑布流就可以达到 类似于QQ空间自动加载的效果,

      

 

三 开发思路

 

  3.1 分析请求

   先用Fiddler 抓取博客园的请求信息大至如下,因为只需要获取文章的信息,不需要做其它操作,所以Cookies部分就可以不考虑,

只要把请求头的相关信息Copy就行了然后添加到HttpWebRequest对象中

  

     3.2 构造请求 并获取响应信息

  通过HttpWebRequest创建一个请求,然后添加请求头信息,最后获取请求的响应信息到HttpWebResponse对象中,并读取出相应数据。  

            HttpWebRequest request = (HttpWebRequest) WebRequest.Create("http://www.cnblogs.com/");
            request.Accept = "text/plain, */*; q=0.01";
            request.Method = "GET";
            request.Headers.Add("Accept-Language", "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");
            request.ContentLength = 0;
            request.ContentType = "keep-alive";
            request.Host = "www.cnblogs.com";
            request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; rv:25.0) Gecko/20100101 Firefox/25.0";

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Stream responStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(responStream,Encoding.UTF8);
            string content = reader.ReadToEnd();

  3.3 通过正则取文章基本信息

   个人觉得最难的部分就在用正则匹配出指定数据,因为没有接触过正则,而且正则又不太容易理解,所以学习正则花了一部分时间,并把正则相关的知识总结成了一篇文章

读懂正则表达式就这么简单 感谢大家的支持。,这里只列取一部分,具体的项目中都有详细的代码 

                    //取推荐
                    regex =new Regex(
                            "<div class=\"digg\">.*<span.*>(?<digNum>.*)" + @"</span>" +
                            ".*<div class=\"post_item_body\">", RegexOptions.Singleline);
                    article.DiggNum = regex.Match(item.Value).Groups["digNum"].Value;

                    //取文章标题 需要去除转义字符
                    regex = new Regex("<h3>(?<a>.*)</h3>", RegexOptions.Singleline);
                    string a = regex.Match(item.Value).Groups["a"].Value;
                    regex = new Regex("<a\\s.*href=\"(?<href>.*?)\".*>(?<summary>.*)</a>", RegexOptions.Singleline);
                    article.AritcleUrl = regex.Match(a).Groups["href"].Value;
                    article.AritcleTitle = regex.Match(a).Groups["summary"].Value;

                    //取作者图片 先取html img标签再取Src
                    regex = new Regex("<a.*>(?<img><img[^>].*>)</a>", RegexOptions.Singleline);
                    string img = regex.Match(item.Value).Groups["img"].Value;
                    regex = new Regex(@"<img.*src=(?<path>.*)\s+.*/>", RegexOptions.Singleline);
                    article.AuthorImg = regex.Match(img).Groups["path"].Value.TrimEnd('"').TrimStart('"');

 

 3.4 把数据返回给插件Masonry

  具体的参数配置官网都有详细的解释,这里就不详细说了,

  $('.container').masonry({
            itemSelector: '.item',
            columnWidth: 230,//一列的宽度 Integer
            isAnimated: true,//使用jquery的布局变化  Boolean  
            animationOptions: {

                Object :{ queue: false, duration: 500 }   //jquery animate属性 渐变效果  
            },
            gutterWidth: 10,//列的间隙 Integer  
            isFitWidth: true,// 适应宽度   Boolean  
            isResizableL: true,// 是否可调整大小 Boolean  
            isRTL: false,//使用从右到左的布局 Boolean  
        });

 

 3.5  通过infinitescroll自动加载数据

  通过触发这个插件infinitescroll的事件,来达到自动加载的效果,这里要注意的是自动加需要一个div 与a 标签,div是分页的容器初始化后会隐藏,而a标签的href属性则

是你要自动加载数据的地址,后面的参数 id=2 默认是从第二页开始,会自动累加。刚开始自己在网上找资料时,没人把这两个元素写出来,让我纠结了好久,我说不给地址

怎么去哪自动加载去啊,找了好久终于让我发现了.....

<div id="page-nav">
    <a href="/GetArticle/GetArticles/?id=2"></a>
</div>
template 的函数返回值就是自动加载后返回的数据可以在DataType属性设定返回的数据格式,注意插件的最后一个回调函数 function (newElements) 要把新的数据添加进瀑布流的布局里就是在这里处理的, 这里的 newElements 其实就是template的返回值,也就是自动加载后重新拼装的数据。
     $('.container').infinitescroll({
            navSelector: '#page-nav',
            nextSelector: '#page-nav a', //下一页选择器
            itemSelector: ".item", //下一页中需要被加载进当前页的块
            extraScrollPx: 150,//滚动条距离底部多少像素的时候开始加载,默认150
            animate: true,
            maxPage:10,//最大页数
            dataType: 'json',
            loading: {
                //加载效果
                finishedMsg: 'No more pages to load',
            },
            template: function (data) {
                //data表示服务端返回的json格式数据,这里需要把data转换成瀑布流块的html格式,然后返回给回到函数
                var article = '';
                for (var i in data) {
                    article += "<li class='item'>" +
                   "<a href=" + data[i].AritcleUrl + " target='_blank'><h3> " + data[i].AritcleTitle + "</h3></a>" +
                    "<p>推荐<b>    " + data[i].DiggNum + "</b> <a href=" + data[i].AuthorUrl + "><img src=" + data[i].AuthorImg + " alt='' /> </a></p>" +
                    "<p style='text-indent: 2em'>" + data[i].AritcleSummary + "</p>" +
                   "<p><a href=" + data[i].AuthorUrl + ">" + data[i].Author + "</a>" + data[i].PublishTime + "</p>" +
                    "<p>" + data[i].CommentNum +"  "+data[i].ReadNum + "</p></li>";
                }
                return article;
            },
        },
            function (newElements) {
                //回调函数,用Masonry布局
                // 当加载时隐藏所有新项目
                var $newElems = $(newElements).css({ opacity: 0 });
                // 现在可以显示所有的元素
                $newElems.animate({ opacity: 1 });
                $('.container').masonry('appended', $newElems, true);
               
            }
        );

 

 通过上面5步就可以把数据正常的加载出来,具体的细节部分喜欢的朋友可以下载源码看看。

 

四 总结

  每次接触新的知识我都尽量会把所学的做一个工具出来,以加强自己的印象。我很享受从构思直到开发完成的这一个过程,在这个过程中收获的东西也很多。

不仅了解了Http相关的知识,还学习了正则与瀑布流和无限滚动,我会继续以这种方式一直走下去....

 

如果您觉得本文有给您带来一点收获,不妨点个推荐,为我的付出支持一下,谢谢~

如果希望在技术的道路上能有更多的朋友,那就关注下我吧,让我们一起在技术的路上奔跑

 

 

 

posted @ 2013-11-28 08:53  Zery  阅读(12576)  评论(49编辑  收藏  举报