“道路千万条,安全第一条!行车不规范,亲人两行泪!”
这句在影片“流浪地球”中不断重复的话语已经被大家所熟知。为了行车的安全,我们需要遵守规范,提前规划。同样,在快节奏生活中的我们,也需要抽出时间来规划自己的娱乐。最简单的规划莫过于周末的时候,看看有没有喜欢的电影上映,以便安排自己的娱乐时间。
今天,我就带着大家来爬取“猫眼电影:最受期待榜”,通过这份榜单,我们可以看到最近这段时间有哪些电影即将上映,这些电影有多少人期待观影。通过这些数据,来辅助我们规划娱乐时间。
首先,我们来看看“猫眼电影:最受期待榜”的原网页,网页地址为:
https://maoyan.com/board/6?offset=0

我们选择“下一页”发现,网址发生了变化,
https://maoyan.com/board/6?offset=10

接着,选择“下一页”,网址变为:
https://maoyan.com/board/6?offset=20
通过观察,我们可以发现爬取网页地址的变化规律,即参数offset
以 10 为步长递增。
爬取的网址有了,我们来看看网页的源码:

我们发现,所有数据都存储在 <dd>
标签内,主演、上映时间、本月新增想看人数、总想看人数存储在 <p>
标签内。
这里值得注意的是,猫眼电影采取了反爬虫机制对“本月新增想看人数”、“总想看人数”进行了加密处理。我们查找 stonefont
类,发现 猫眼电影 使用 font-face
定义字符集,并通过 unicode 去映射展示,所以我们在网页上看到的是数字,但是在源码中看到的却是别的字符。


如何破解猫眼电影的反爬虫机制呢?我会在后面专门写一篇图文来介绍。这里暂且搁置一下。
影片详细信息展示的网址,可通过 <a>
标签的 href
属性获取,如上图对应影片“惊奇队长”的网址为:
https://maoyan.com/films/341139

我们查看该网页对应的源代码,发现影片的类型存储在 li.ellipsis
类中,影片的简介存储在 dra
类中。

通过以上的分析,只要我们得到相应网页的HTML DOM TREE
,使用选择器找到对应位置,就能提取出相应的数据。获取HTML DOM TREE
,我推荐一套开源类库 Jumony,可以在 Github 上下载。下载地址为:
https://github.com/Ivony/Jumony

这里对 Jumony 就不做过多介绍了,要是大家感兴趣,可以在图文下方留言,我后面再写几篇图文来介绍这个工具。
到此为止,网页分析、所用工具已经介绍完了,下面介绍一下我们写的代码。
1.定义存储电影的结构 Film
。包含排名、名称、类型、本月新增想看人数、总想看人数、主演、上映时间、简介等。
/// <summary>
/// 表示电影的类
/// </summary>
public class Film
{
/// <summary>
/// 获取或设置 排名
/// </summary>
public int Num { get; set; }
/// <summary>
/// 获取或设置 名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 获取或设置 类型
/// </summary>
public string Type { get; set; }
/// <summary>
/// 获取或设置 本月新增想看
/// </summary>
public string NewWatcher { get; set; }
/// <summary>
/// 获取或设置 总想看
/// </summary>
public string TotalWatcher { get; set; }
/// <summary>
/// 获取或设置 主演
/// </summary>
public string Actor { get; set; }
/// <summary>
/// 获取或设置 上映时间
/// </summary>
public string Time { get; set; }
/// <summary>
/// 获取或设置 简介
/// </summary>
public string Introduction { get; set; }
/// <summary>
/// Markdown格式化输出
/// </summary>
/// <returns></returns>
public override string ToString()
{
string str = Environment.NewLine
+ "---" + Environment.NewLine
+ "## Top" + Num.ToString().PadLeft(2, '0') + " <br>"
+ Name + Environment.NewLine
+ "- 类型:" + Type + Environment.NewLine
+ "- 主演:" + Actor + Environment.NewLine
+ "- 上映时间:" + Time + Environment.NewLine
+ "- 本月新增想看:<span style='color:#FF8F00'><b>"
+ NewWatcher
+ "</b></span>" + Environment.NewLine
+ "- 总想看:<span style='color:#757575'><b>"
+ TotalWatcher
+ "</b></span>" + Environment.NewLine
+ "- 剧情简介:" + Introduction
+ Environment.NewLine;
return str;
}
}
2. 根据URL
得到对应的HTML DOM TREE
。
offset
:对应要抓取「猫眼电影:最受期待榜」哪一页的数据,间隔为10。
public static IHtmlDocument GetHtmlDocument(string url, int offset)
{
IHtmlDocument document;
try
{
document = new JumonyParser().LoadDocument(url 、
+ "?offset=" + offset);
}
catch
{
document = null;
}
return document;
}
3. 得到「猫眼电影:最受期待榜」的数据。
public static List<Film> GetFilmsExpect(int offset)
{
List<Film> result = new List<Film>();
//最受期待榜
string url = "https://maoyan.com/board/6";
IHtmlDocument doc = GetHtmlDocument(url, offset);
if (doc == null)
return result;
List<IHtmlElement> lists = doc.Find("dd").ToList();
for (int i = 0; i < lists.Count; i++)
{
List<IHtmlElement> infor = lists[i].Find("p").ToList();
Film item = new Film();
//排名
item.Num = i + 1;
//演员
item.Actor = infor[1].InnerHtml().Trim().Remove(0, 3);
//上映时间
item.Time = infor[2].InnerHtml().Trim().Remove(0, 5);
string dw = infor[3].InnerHtml().Trim();
dw = dw.Remove(0, dw.Length - 1); //单位
List<IHtmlElement> p = infor[3].Find(".stonefont").ToList();
//加密的新增想看人数
string people = p[0].InnerHtml().Trim();
item.NewWatcher = GetPeople(people) + dw; //解密的新增想看人数
dw = infor[4].InnerHtml().Trim();
dw = dw.Remove(0, dw.Length - 1); //单位
p = infor[4].Find(".stonefont").ToList();
people = p[0].InnerHtml().Trim(); //加密的总想看人数
item.TotalWatcher = GetPeople(people) + dw; //解密的总想看人数
IHtmlElement a = infor[0].Find("a").ToList()[0]; //获取影片url
item.Name = a.InnerHtml().Trim(); //名称
url = "https://maoyan.com" + a.Attribute("href").AttributeValue;
IHtmlDocument temp = GetHtmlDocument(url);
List<IHtmlElement> t = temp.Find("li.ellipsis").ToList();
item.Type = t[0].InnerHtml(); //类型
List<IHtmlElement> b = temp.Find(".dra").ToList();
item.Introduction = b[0].InnerHtml(); //介绍
result.Add(item);
}
return result;
}
4. 得到 Markdown 格式化输出的「猫眼电影:最受期待榜」。
private string GetReportExpect(List<Film> lst)
{
string result = Environment.NewLine;
for (int i = 0; i < lst.Count; i++)
{
result += lst[i].ToString() + Environment.NewLine
+ "广告" + Environment.NewLine;
}
return result;
}
5. 渲染 Markdown 格式化输出的结果。

最后,我们再来总结一下。
通过对“猫眼电影:最受期待榜”的网页分析,我们确定了爬取网页的 URL
地址结构,利用 Jumony 开源类库得到该网页的 HTML DOM TREE
,使用选择器得到对应的电影数据集合,最后格式化输出为 Markdwon 文本。经过渲染可以构成我们每周五推荐的 猫眼电影:「即将上映、最受期待」榜 的图文内容。(这里剩下 如何破解猫眼电影的“字体反爬策略”,后面再写一篇图文详细介绍。)
怎么样,是不是很有趣。大家来试试看,今天就到这里吧,See You!
推荐阅读
网友评论