zoukankan      html  css  js  c++  java
  • 采集博客园文章,用瀑布流+无限滚动展示(附源码)

    一 前言

      前段时间一直在了解关于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相关的知识,还学习了正则与瀑布流和无限滚动,我会继续以这种方式一直走下去....

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

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

  • 相关阅读:
    arduino链接GY521(MPU6050)模块
    I2C Python Library ITG3205 API
    [翻译]AxureInteractive Prototypes原型设计工具Axure学习第2.3节
    [Java]XML数据的请求和DOM技术解析
    [Linux]VI相关操作
    mysql数据库连接错误问题
    关于管理单元初始化失败的解决方法
    彻底明白Java的IO系统(网上找的,还没看,先放这)
    一个关于C++ Inline关键字的引发的一个错误
    orcale 中日期类型相加的处理
  • 原文地址:https://www.cnblogs.com/zery/p/3446746.html
Copyright © 2011-2022 走看看