在现代生活中,看电影已经成为大家的一种休闲方式。
前几天,我们介绍了 如何利用 C# 爬取「猫眼电影:热映口碑榜」及对应影片信息!,通过这份“热映口碑”榜单,我们可以看到大家对当前热播电影的评价,为我们选择所要观看的电影提供了辅助支持。但仅有这份榜单还是不够的,我们还想知道这些热映电影更详细的数据,比如:“实时票房”、“累积票房”、“票房占比”、“排片占比”、“上座率”等等,以便更好的选择出一部令自己满意的影片,更好的分配自己的娱乐时间。
下面,我就带大家从“猫眼专业版”的网站上来爬取以上的数据。
首先,我们浏览一下“猫眼专业版”的网页,网址如下(选择2019年03月01日的数据):
https://piaofang.maoyan.com/dashboard?date=2019-03-01
对应的源代码如下:
注:如果需要选择2019年03月02日的数据,只需要调整URL
中的date
参数值,把2019-03-01
换为2019-03-02
即可。
https://piaofang.maoyan.com/dashboard?date=2019-03-02
其次,我们从源代码中发现<div class="movielist"></div>
部分,并不包含数据,初步断定该网页采用了“前后端分离”的开发方式。故打开浏览器的控制台,发现了确实从服务器请求的JSON
数据,请求网址如下:
https://box.maoyan.com/promovie/api/box/second.json?beginDate=20190301
对应的JSON
数据如下:
我们想要的数据包含在list
数组中,如下图所示:
这样,我们就找到了所要获取的JSON
数据。
怎样处理JSON
数据呢?我这里使用了一套处理JSON
数据的开源类库Json.NET
,通过这套类库可以把得到的JSON
数据反序列化成对应的类型。Json.NET
的 Git 网址如下:
https://github.com/JamesNK/Newtonsoft.Json
有需要的同学可以到 Git 上下载源码,这里就不过多介绍这个开源类库了。如果对大家对Json.NET
感兴趣可以在图文下面留言,我会另外写一些图文详细介绍这套类库的源码以及具体应用。
到此为止,网页的分析部分就介绍完了,下面我们来看具体的代码部分:
1. 定义存储电影的结构Film
。包括“编号、名称、实时票房、总票房、票房占比、排片占比、上座率”等等。
public class Film
{
/// <summary>
/// 获取或设置 编号
/// </summary>
public int Num { get; set; }
/// <summary>
/// 获取或设置 名称
/// </summary>
public string MovieName { get; set; }
/// <summary>
/// 获取或设置 实时票房
/// </summary>
public string BoxInfo { get; set; }
/// <summary>
/// 获取或设置 票房占比
/// </summary>
public string BoxRate { get; set; }
/// <summary>
/// 获取或设置 排片占比
/// </summary>
public string ShowRate { get; set; }
/// <summary>
/// 获取或设置 总票房
/// </summary>
public string SumBoxInfo { get; set; }
/// <summary>
/// 获取或设置 上座率
/// </summary>
public string AvgSeatView { get; set; }
/// <summary>
/// Markdown 格式化输出
/// </summary>
/// <returns></returns>
public override string ToString()
{
string str = Environment.NewLine
+ "---" + Environment.NewLine
+ "## Top" + Num.ToString().PadLeft(2, '0') + " <br>"
+ MovieName + Environment.NewLine
+ "- 实时票房:<span style='color:#E53935'><b>" + BoxInfo
+ "</b></span>" + Environment.NewLine
+ "- 票房占比:<span style='color:#E53935'><b>" + BoxRate
+ "</b></span>" + Environment.NewLine
+ "- 排片占比:<span style='color:#E53935'><b>" + ShowRate
+ "</b></span>" + Environment.NewLine
+ "- 上座率:<span style='color:#E53935'><b>" + AvgSeatView
+ "</b></span>" + Environment.NewLine
+ "- 总票房:<span style='color:#757575'><b>" + SumBoxInfo
+ "</b></span>" + Environment.NewLine;
return str;
}
}
2. 根据URL
得到包含电影数据的JSON
。
public static string GetFilmsJson(string url)
{
//1. HttpWebRequest 发送HTTP数据
HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest;
if (webRequest == null)
return string.Empty;
webRequest.Method = "GET";
webRequest.ContentType = "application/json;charset=utf-8";
webRequest.Accept = "*/*";
try
{
string json;
using (HttpWebResponse webResponse = (HttpWebResponse) webRequest.GetResponse())
//2.HttpWebResponse 接收HTTP数据
{
Stream st = webResponse.GetResponseStream();
if (st == null)
return string.Empty;
using (StreamReader reader = new StreamReader(st, Encoding.UTF8))
{
json = reader.ReadToEnd();
reader.Close();
webResponse.Close();
}
}
return json;
}
catch
{
return string.Empty;
}
}
3. 为反序列化该JSON
定义对应的结构。
这块定义的结构与JSON
的格式相对应,可以结合上面JSON
数据的图来看。
private class Item
{
/// <summary>
/// 上座率
/// </summary>
public string avgSeatView { get; set; }
/// <summary>
/// 实时票房
/// </summary>
public string boxInfo { get; set; }
/// <summary>
/// 票房占比
/// </summary>
public string boxRate { get; set; }
/// <summary>
/// 排片占比
/// </summary>
public string showRate { get; set; }
/// <summary>
/// 名称
/// </summary>
public string movieName { get; set; }
/// <summary>
/// 总票房
/// </summary>
public string sumBoxInfo { get; set; }
}
private class Data
{
public List<Item> list;
}
private class JsonFilm
{
public Data data { get; set; }
}
4. 反序列化JSON
到对应的类中,并得到存储电影数据的链表。
public static List<Film> GetFilmsMaoYanTicket(string date)
{
List<Film> result = new List<Film>();
string url = @"https://box.maoyan.com/promovie/api/box/"
+@"second.json?beginDate="
+ date;
//通过JSON的方式来实现
string json = GetFilmsJson(url);
StringReader sr = new StringReader(json);
JsonTextReader jsonReader = new JsonTextReader(sr);
JsonSerializer serializer = new JsonSerializer();
JsonFilm r = serializer.Deserialize<JsonFilm>(jsonReader);
List<Item> lst = r.data.list;
for (int i = 0, len = lst.Count; i < len; i++)
{
Film film = new Film();
film.Num = i + 1;
film.MovieName = lst[i].movieName;
film.AvgSeatView = lst[i].avgSeatView;
film.BoxInfo = lst[i].boxInfo + "万";
film.BoxRate = lst[i].boxRate;
film.ShowRate = lst[i].showRate;
film.SumBoxInfo = lst[i].sumBoxInfo;
result.Add(film);
}
return result;
}
5. Markdown 格式化输出爬取的“猫眼电影专业版:票房”的数据。
private string GetReportReputation(List<Film> lst)
{
string result = Environment.NewLine;
for (int i = 0; i < lst.Count; i++)
{
result += lst[i].ToString() + Environment.NewLine;
}
return result;
}
6. 把Markdown
格式的文本渲染成HTML
格式的文本。
以上我们分析了“猫眼电影专业版”的网页,得知该网页采取了前后端分离的开发方式,于是我们先得到了存储信息的JSON
数据,并利用Json.net
类库对其反序列化,得到对应的类,从而完成了整个网页的爬取过程。
是不是很有趣,大家也来试试吧!今天就到这里了,See You!
参考图文: