把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;
模型:

附上控制器內完整代碼:

第四步:數據顯示在首頁
因為網站首頁的左側背景圖是一個母版頁,所以圖片的顯示主要通過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);
});
})