zoukankan      html  css  js  c++  java
  • 抓取Bing每日图片作为网站首页背景

    把Bing搜索的背景图片设置为自己网站的背景,实现背景及资讯的每日更新

    效果图如下:

    理一下思路,首先我们要抓取Bing的每日图片及最新资讯,然后保存图片及信息到本地,最后显示图片及资讯到网站首页。

    第一步:抓取图片

      首先打开Bing,然后使用开发者工具 F12,点击审查网页元素,分析HTML结构如下图:

         

      这里可以看到背景的图片地址,这就准备从HTML元素中获取图片链接了。于是我还下载了Jumony 一个提取网页元素的帮助类,来获取background-image的元素(Jumony的使用可以直接在NuGet管理中搜索Jumony,然后安装,最后记得引用命名空间,Jumony的详细使用请移步http://www.cnblogs.com/Ivony/p/3447536.html

      

      结果发现 获取的HTML标签里并没有CSS的属性,那也就取不到 背景图片的URL了,然后怎么办呢?

      继续使用开发者工具查看Bing网页,发现了一个Ajax请求,返回了一个Json数据,如下图:

      

      说明这个请求返回的Json就是Bing的每日图片的信息,这就能得到图片信息的请求网址了,查看消息头:

      

      请求网址:http://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&nc=1470798060031&pid=hp&video=1

      然后检测请求中可以省略的参数,最后得到URL:http://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1

          接下来就需要在程序中获取Json数据,使用WebClient 进行网页请求:

      

      这时我们就要对Json进行解析,获取我们想要的数据,也就是背景图片的URL:

      对Json的解析有很多方法:Json转换为dataTable,Json反序列化,也有第三方组件等,

      这里用自己比较擅长的方法:VS自带的javaScriptSerializer类将wallejson转换为模型,这个模型根据返回的Json数据结构创建

      解析完之后就得到了图片的URL,根据WebClient的DownLoadFile()方法保存图片到本地;

      附上模型:

     1  //用于解析Bing返回的Json数据
     2 
     3 
     4     public class Walle
     5     {
     6         public  List<images> images { get; set; }
     7         public tooltips tooltips { get; set; }
     8     }
     9 
    10     public class images
    11     {
    12         public string startdate { get; set; }
    13         public string fullstartdate { get; set; }
    14         public string enddate { get; set; }
    15         public string url { get; set; }
    16         public string urlbase { get; set; }
    17         public string copyright { get; set; }
    18         public string copyrightlink { get; set; }
    19         public string wp { get; set; }
    20         public string hsh { get; set; }
    21         public string drk { get; set; }
    22         public string top { get; set; }
    23         public string bot { get; set; }
    24         public List<int> hs { get; set; }
    25 
    26 
    27     }
    28 
    29     public class tooltips
    30     {
    31         public string loading { get; set; }
    32         public string previous { get; set; }
    33         public string next { get; set; }
    34         public string walle { get; set; }
    35         public string walls { get; set; }
    36 
    37     }

     

    第二步:获取每日资讯

      我们要获取这里的数据:

    
    

      继续使用开发者工具查看数据的位置:

      

      这就可以使用Jumony抓取数据了吧,和刚开始一样,

      结果很郁闷,在HTML页面中找不到类名为"hplaCata"的元素内容。

      仔细查看了网络连接后,发现了一个很有意思的事情:

      如下图:

         

      打开这个请求后:

      

        原来是个单独的页面,怪不得在原来的页面上找不到,接下来就好办了:

        保存这个页面的请求:http://cn.bing.com/cnhp/life?currentDate=20160809&IID=SERP.5045&IG=CC0CACB23C324D99A37ACF3604BF19FE,

      经过简单的测试,currentDate是当天的日期,其他的参数则不需要。

      下面直接看代码,根据Jumony抓取数据:

      

     string date = DateTime.Now.ToString("yyyyMMdd");
    
    
                //获取文本信息
                string BingUrl = "https://cn.bing.com/cnhp/life?currentDate="+date;
    
                var Source = new JumonyParser().LoadDocument(BingUrl);
                string Title="";
                string Text="";
    
                //标题
                foreach (var item in Source.Find(".hplaCata > .hplatt"))
                {
                     Title = item.InnerText();
                }
    
                //文本
                foreach (var item in Source.Find("#hplaSnippet"))
                {
                    Text = item.InnerText();
                }

    第三步:保存数据到本地

        前面两步已经获取到了图片以及资讯,然后应该保存数据了,

        一般来说我们都是保存图片路径 和 资讯数据到数据库,不过需求是替换原来的网站首页背景,偏向于对UI的改进,再动数据库就不太合适了。

        而且,图片会每日更新,系统则自动获取,这些数据只提供每天的查询,写操作则一天一次。

        解决思路:图片以当前日期为文件名,资讯信息以XML形式,文件名也是当前日期(如20160810)保存到网站目录下,每次首页加载都会查看以当前日期为文件名的Xml文件或JPG文件是否存在,不存在就执行程序抓取Bing图片和每日资讯,存在则获取数据传递给首页显示。

        保存资讯为XML,这里我用的是XmlSerializer,将Model转换并创建XML文件,这个Model主要根据保存的信息来创建,字段有: 标题,副标题,文本信息,图片路径,当前日期。获取数据时反序列化XML为Model;    

        模型:

        

     1  /// <summary>
     2     /// 用于保存和传输Bing背景图片及文本信息
     3     /// </summary>
     4     public  class BgImages
     5     {
     6         /// <summary>
     7         /// 标题
     8         /// </summary>
     9         public string Title { get; set; }
    10 
    11         /// <summary>
    12         /// 副标题
    13         /// </summary>
    14         public string STitle { get; set; }
    15         /// <summary>
    16         /// 文本
    17         /// </summary>
    18         public string Text { get; set; }
    19         /// <summary>
    20         /// 图片路径
    21         /// </summary>
    22         public string Url { get; set; }
    23         /// <summary>
    24         /// 保存日期
    25         /// </summary>
    26         public string Date { get; set; }
    27     }
    View Code

        

        附上控制器内完整代码:      

      1    #region  联网抓取图片
      2 
      3         /// <summary>
      4         /// 读取背景信息
      5         /// </summary>
      6         /// <returns></returns>
      7         public ActionResult ReturnBgInfo()
      8         {
      9             //读取XML文件
     10             string Path = Server.MapPath("/Images/BingInfo/" + DateTime.Now.ToString("yyyyMMdd") + ".xml");
     11 
     12             FileInfo file = new FileInfo(Path);
     13 
     14             if (!file.Exists)
     15             {
     16                 GetNewBing();
     17             }
     18 
     19             FileStream files = new FileStream(Path, FileMode.Open);
     20             XmlSerializer xml = new XmlSerializer(typeof(BgImages));
     21             BgImages BgImage = (BgImages)xml.Deserialize(files);
     22             files.Close();
     23 
     24             return Json(BgImage);
     25 
     26         }
     27 
     28         /// <summary>
     29         /// //联网抓取图片
     30         /// </summary>
     31         public void GetNewBing()
     32         {
     33             string date = DateTime.Now.ToString("yyyyMMdd");
     34 
     35 
     36             //获取文本信息
     37             string BingUrl = "https://cn.bing.com/cnhp/life?currentDate=" + date;
     38 
     39             var Source = new JumonyParser().LoadDocument(BingUrl);
     40             string Title = "";
     41             string Text = "";
     42             string STitle = "";
     43 
     44             //标题
     45             foreach (var item in Source.Find(".hplaCata > .hplatt"))
     46             {
     47                 Title = item.InnerText();
     48             }
     49 
     50             //副标题
     51             foreach (var item in Source.Find(".hplaCata > .hplats"))
     52             {
     53                 STitle = item.InnerText();
     54             }
     55 
     56             //文本
     57             foreach (var item in Source.Find("#hplaSnippet"))
     58             {
     59                 Text = item.InnerText();
     60             }
     61 
     62 
     63             //Bing网址
     64             string url = "http://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1";
     65 
     66             //获取Bing的图片 Json数据
     67             WebClient BingClient = new WebClient();
     68             BingClient.Encoding = System.Text.Encoding.UTF8;//定义对象的编码语言,此处或者是gb2312
     69             string wallejson = BingClient.DownloadString(url);
     70 
     71             if (wallejson != "null")
     72             {
     73                 //解析Json数据
     74                 JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
     75                 Walle walleinfo = javaScriptSerializer.Deserialize<Walle>(wallejson);
     76 
     77                 //保存图片到本地
     78                 string ImagePath = DateTime.Now.ToString("yyyyMMdd") + ".JPG";
     79                 BingClient.DownloadFile(walleinfo.images.First().url, Server.MapPath("/Images/BingInfo/") + ImagePath);
     80 
     81                 //保存信息到Model -- BgImages
     82                 BgImages model = new BgImages();
     83                 model.Date = walleinfo.images.First().enddate;
     84                 model.Text = Text;
     85                 model.Title = Title;
     86                 model.STitle = STitle;
     87                 model.Url = "/Images/BingInfo/" + ImagePath;
     88 
     89                 string xmlPath = Server.MapPath("/Images/BingInfo/" + DateTime.Now.ToString("yyyyMMdd") + ".xml");
     90 
     91                 //序列化XML
     92                 CreateXML(model, xmlPath);
     93 
     94             }
     95 
     96         }
     97 
     98 
     99 
    100 
    101         #region   XML序列化
    102         public void CreateXML(BgImages model, string Path)
    103         {
    104             FileStream fs = new FileStream(Path, FileMode.Create);
    105             //执行XML序列化
    106             XmlSerializer xml = new XmlSerializer(typeof(BgImages));
    107             xml.Serialize(fs, model);
    108             fs.Close();
    109         }
    110         #endregion
    111         #endregion
    View Code

        

    第四步:数据显示在首页

      因为网站首页的左侧背景图是一个母版页,所以图片的显示主要通过js来实现。

      在页面加载时,使用Ajax请求在后台获取数据,

      代码如下:

     $(document).ready(function () {
          
    
    
            //加载背景图片及文本信息
            $.post(
               "/Test/ReturnBgInfo",
               function (data) {
    
    
                   $("#animate-area").css("background-image", "url(" + data.Url + ")");
                   $("#Title").html(data.Title);
                   $("#STitle").html(data.STitle);
                   $("#Text").html(data.Text);
    
               });
    })
    

      

  • 相关阅读:
    EF
    采用什么架构,才能够承受大访问量
    13个MVC的扩展
    c#与.NET的区别
    整合Spring.net到asp.net网站开发中初探
    C#多线程编程简述
    ASP.NET页面传值的几种方式
    正则RegEXp
    C#中Cache用法
    c#程序将excel文件转换成xml文件
  • 原文地址:https://www.cnblogs.com/YQZXH/p/5756425.html
Copyright © 2011-2022 走看看