抓取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()方法保存图片到本地;
附上模型:
//用于解析Bing返回的Json数据
public class Walle
{
public List<images> images { get; set; }
public tooltips tooltips { get; set; }
}
public class images
{
public string startdate { get; set; }
public string fullstartdate { get; set; }
public string enddate { get; set; }
public string url { get; set; }
public string urlbase { get; set; }
public string copyright { get; set; }
public string copyrightlink { get; set; }
public string wp { get; set; }
public string hsh { get; set; }
public string drk { get; set; }
public string top { get; set; }
public string bot { get; set; }
public List<int> hs { get; set; }
}
public class tooltips
{
public string loading { get; set; }
public string previous { get; set; }
public string next { get; set; }
public string walle { get; set; }
public string walls { get; set; }
}
第二步:获取每日资讯
我们要获取这里的数据:

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

这就可以使用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;
模型:
/// <summary>
/// 用于保存和传输Bing背景图片及文本信息
/// </summary>
public class BgImages
{
/// <summary>
/// 标题
/// </summary>
public string Title { get; set; } /// <summary>
/// 副标题
/// </summary>
public string STitle { get; set; }
/// <summary>
/// 文本
/// </summary>
public string Text { get; set; }
/// <summary>
/// 图片路径
/// </summary>
public string Url { get; set; }
/// <summary>
/// 保存日期
/// </summary>
public string Date { get; set; }
}
附上控制器内完整代码:
#region 联网抓取图片
/// <summary>
/// 读取背景信息
/// </summary>
/// <returns></returns>
public ActionResult ReturnBgInfo()
{
//读取XML文件
string Path = Server.MapPath("/Images/BingInfo/" + DateTime.Now.ToString("yyyyMMdd") + ".xml");
FileInfo file = new FileInfo(Path);
if (!file.Exists)
{
GetNewBing();
}
FileStream files = new FileStream(Path, FileMode.Open);
XmlSerializer xml = new XmlSerializer(typeof(BgImages));
BgImages BgImage = (BgImages)xml.Deserialize(files);
files.Close();
return Json(BgImage);
}
/// <summary>
/// //联网抓取图片
/// </summary>
public void GetNewBing()
{
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 = "";
string STitle = "";
//标题
foreach (var item in Source.Find(".hplaCata > .hplatt"))
{
Title = item.InnerText();
}
//副标题
foreach (var item in Source.Find(".hplaCata > .hplats"))
{
STitle = item.InnerText();
}
//文本
foreach (var item in Source.Find("#hplaSnippet"))
{
Text = item.InnerText();
}
//Bing网址
string url = "http://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1";
//获取Bing的图片 Json数据
WebClient BingClient = new WebClient();
BingClient.Encoding = System.Text.Encoding.UTF8;//定义对象的编码语言,此处或者是gb2312
string wallejson = BingClient.DownloadString(url);
if (wallejson != "null")
{
//解析Json数据
JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
Walle walleinfo = javaScriptSerializer.Deserialize<Walle>(wallejson);
//保存图片到本地
string ImagePath = DateTime.Now.ToString("yyyyMMdd") + ".JPG";
BingClient.DownloadFile(walleinfo.images.First().url, Server.MapPath("/Images/BingInfo/") + ImagePath);
//保存信息到Model -- BgImages
BgImages model = new BgImages();
model.Date = walleinfo.images.First().enddate;
model.Text = Text;
model.Title = Title;
model.STitle = STitle;
model.Url = "/Images/BingInfo/" + ImagePath;
string xmlPath = Server.MapPath("/Images/BingInfo/" + DateTime.Now.ToString("yyyyMMdd") + ".xml");
//序列化XML
CreateXML(model, xmlPath);
}
}
#region XML序列化
public void CreateXML(BgImages model, string Path)
{
FileStream fs = new FileStream(Path, FileMode.Create);
//执行XML序列化
XmlSerializer xml = new XmlSerializer(typeof(BgImages));
xml.Serialize(fs, model);
fs.Close();
}
#endregion
#endregion
第四步:数据显示在首页
因为网站首页的左侧背景图是一个母版页,所以图片的显示主要通过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);
});
})
抓取Bing每日图片作为网站首页背景的更多相关文章
- 【PHP】使用PHP抓取Bing每日图像并为己所用
Bing搜索的首页每天都会推送一张很漂亮的图片,把它保存下来,当做电脑桌面或是自己的网站背景图还不是美滋滋…… 今天的bing图片是这样的 既然要抓取这张图片,首先就得弄清这张图是从何而来的.经过对必 ...
- 获取Bing每日图片API接口
bing图片每日更新,对于这一点感觉挺不错的,如果能够把bing每日图片作为博客背景是不是很不错呢?首先我们进入Bing首页,会发现自动转到中国版.不过这没关系,中国版更符合国情,速度也比国际版快一些 ...
- python抓取bing主页背景图片
最初Python2写法: #!/usr/bin/env python # -*- coding:utf-8 -*- # -*- author:nancy -*- # python2抓取bing主页所有 ...
- PHP批量抓取远程网页图片并存到本地实现方法和源码
做为一个仿站工作者,当遇到网站有版权时甚至加密的时候,WEBZIP也熄火,怎么扣取网页上的图片和背景图片呢.有时候,可能会想到用火狐,这款浏览器好像一个强大的BUG,文章有版权,屏蔽右键,火狐丝毫也不 ...
- 使用wget工具抓取网页和图片 成功尝试
使用wget工具抓取网页和图片 发表于1年前(2014-12-17 11:29) 阅读(2471) | 评论(14) 85人收藏此文章, 我要收藏 赞7 wget 网页抓取 图片抓取 目录[-] ...
- 使用wget工具抓取网页和图片 及 相关工具几个
想保存一些网页,最后找到这 wget 的 shell脚本,虽然不是太理想,亲测可用呢. 使用wget工具抓取网页和图片 来源 https://my.oschina.net/freestyletim ...
- 必应(Bing)每日图片获取API
必应(Bing)每日图片获取API January 11, 2015 API http://lab.dobyi.com/api/bing.php 介绍 Value Description title ...
- python学习-抓取知乎图片
#!/bin/usr/env python3 __author__ = 'nxz' """ 抓取知乎图片webdriver Chromedriver驱动需要安装,并指定d ...
- 【Python爬虫程序】抓取MM131美女图片,并将这些图片下载到本地指定文件夹。
一.项目名称 抓取MM131美女写真图片,并将这些图片下载到本地指定文件夹. 共有6种类型的美女图片: 性感美女 清纯美眉 美女校花 性感车模 旗袍美女 明星写真 抓取后的效果图如下,每个图集是一个独 ...
随机推荐
- bzoj 1879 [Sdoi2009]Bill的挑战(状压DP)
Description Input 本题包含多组数据. 第一行:一个整数T,表示数据的个数. 对于每组数据: 第一行:两个整数,N和K(含义如题目表述). 接下来N行:每行一个字符串. Output ...
- Java 并发之线程安全
写线程安全的代码,说白了就是管理一个类的共享的.可变的状态.只要有多于 1 个线程对类的状态进行写入,那么就必须用同步来协调这多个线程对状态的访问.对于一个没有状态的类来说(简单的理解就是只有方法没有 ...
- weka 集成学习
import java.io.*;import weka.classifiers.*;import weka.classifiers.meta.Vote;import weka.core.Instan ...
- 开始使用storm
开始使用storm 本章将讲述如何安装.部署.启动和停止 Storm 集群. Storm 的安装比较简单,但在安装 Storm 之前需要做好充足的准备,本章将介绍安装的整个流程.在官网上可以下载到S ...
- 问题-提示“adodataset.command”
问题现象:提示“adodataset.command” 问题原因:原因不明,希望高人指点. 问题处理:如果报adodataset.command ,如果忽略将删除控件的错误时,你应该可以看一看是不是在 ...
- [五]JFreeChart实践四之直线图
重点: 1.时间序列集合作为dataset,一个时间序列为一条折线 2.时间序列可以是月:年,小时:天 3.准备好时间序列要放入时间序列集合中 4.将时间序列集合作为dataset传入ChartFac ...
- 2016-11-15NOIP模拟赛
AM学军OJ T1 暴力 #include<bits/stdc++.h> using namespace std; typedef long long LL; + ; int len, p ...
- 如何通过进程名获取进程ID
博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:如何通过进程名获取进程ID.
- 读取xml格式文件
$v = [xml]get-content d:\vmconfig.xml $v.Domain.Computer.Name =========================== $v.GetElem ...
- jQuery源代码学习笔记:构造jQuery对象
2.1源代码结构: (function( window, undefined ) { var jQuery = (function() { // 构建jQuery对象 var jQuery = fun ...