在 如何利用 C# 爬取「猫眼电影:最受期待榜」及对应影片信息! 这篇图文中可以看到猫眼电影对“本月新增想看人数” 和 “总想看人数”进行了字符集加密。

在 如何利用 C# 爬取「猫眼电影:国内票房榜」及对应影片信息! 这篇图文中也可以看到猫眼电影对“实时票房” 和 “总票房”进行了字符集加密。

破解这种利用字符集加密的反爬虫机制,需要建立映射关系表,找到每个字符对应的真实数字即可。怎么做呢?

我们 首先 需要把对应的字符集下载到本地。

然后,把该字符集转换成XML文件。由于 Python 中有 TTFont 指令可以直接使用,于是把转换的功能用 Python 来写并用 pyinstaller 指令打包成 EXE 文件,通过 C# 语言进行调用即可。

imports sys
from fontTools.ttLib import TTFontif __name__ =='__main__'font1 = TTFont(str(sys.argv[1]))font1.saveXML(str(sys.argv[2]))

打包main.py文件的代码:

pyinstaller -F main.py

生成的 XML 文件如下:

接着,建立映射关系表,把TTGlyph namecountour和真实的数据对应起来。这个不能自动化只能把网页上的数字与源代码中的字符对应,在通过源代码中的字符与这个XML中的 TTGlyph name对应。

最后,可以通过加载这份映射表来破解猫眼电影的反爬虫机制。即我先在内存中加载这份映射表,每个字体的图形名称TTGlyph name在刷新后是变化的,但图形信息countour是不会变化的,所以可以先通过图形名称找到图形信息,在通过这份映射表找到对应的真实数字。


以上详细的介绍了破解猫眼电影反爬虫机制的方法,下面我们来写具体的代码。

1. 构造字体图形的结构 FontGlyph

public class FontGlyph
{/// <summary>/// 图形名称/// </summary>public string Name { get; set; }/// <summary>/// 图形数据/// </summary>public string Glyph { get; set; }/// <summary>/// 图形值/// </summary>public int Value { get; set; } = -1;
}

2. 获取字体 WOFF 文件的存储地址

private static string GetWoffUrl(string str)
{int end = str.IndexOf(@"') format('woff')", StringComparison.Ordinal);int start = str.LastIndexOf("//vfile.meituan.net", StringComparison.Ordinal);string url = str.Substring(start, end - start);return "http:" + url;
}

3. 下载字体 WOFF 文件到本地

private static string Download(string url)
{int index = url.LastIndexOf("/", StringComparison.Ordinal);string fileName = @".\font\" + url.Substring(index + 1);HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;if (request == null)return string.Empty;HttpWebResponse response = request.GetResponse() as HttpWebResponse;if (response == null)return string.Empty;Stream reponseStream = response.GetResponseStream();if (reponseStream == null)return string.Empty;Stream stream = new FileStream(fileName, FileMode.Create);byte[] bArr = new byte[1024];int size = reponseStream.Read(bArr, 0, bArr.Length);while (size > 0){stream.Write(bArr, 0, size);size = reponseStream.Read(bArr, 0, bArr.Length);}stream.Close();reponseStream.Close();return fileName;
}

4. 转换字体 WOFF 文件为XML文件

private static string TransXml(string fileName)
{string xml = @".\font\" + Path.GetFileNameWithoutExtension(fileName) + ".xml";Process p = new Process();p.StartInfo.FileName = @".\font\main.exe";p.StartInfo.UseShellExecute = false;p.StartInfo.RedirectStandardOutput = true;p.StartInfo.RedirectStandardInput = true;p.StartInfo.CreateNoWindow = true;p.StartInfo.Arguments = fileName + " " + xml;p.Start();p.WaitForExit();p.Close();return xml;
}

5. 根据 XML 文件获得字体图形文件列表 List<FontGlyph>

private static List<FontGlyph> GetXmlGlyf(string path)
{List<FontGlyph> result = new List<FontGlyph>();XmlDocument xmldoc = new XmlDocument();XmlReaderSettings settings = new XmlReaderSettings();settings.IgnoreComments = true;XmlReader reader = XmlReader.Create(path, settings);xmldoc.Load(reader);if (xmldoc.DocumentElement == null)return result;XmlNodeList nodeList = xmldoc.DocumentElement.ChildNodes;foreach (XmlNode node in nodeList){if (node.Name == "glyf"){XmlNodeList lst = node.ChildNodes;foreach (XmlNode n in lst){XmlElement xe = n as XmlElement;if (xe != null){if (string.IsNullOrEmpty(xe.InnerXml) == false){FontGlyph item = new FontGlyph();item.Name = xe.GetAttribute("name");item.Glyph = xe.InnerXml;item.Value = -1;result.Add(item);}}}}}return result;
}

6. 建立映射关系

private static int GetValue(string name)
{string[] str = new string[]{"uniF756", "uniED75", "uniF8F8", "uniF81A", "uniEE70", "uniECA0","uniEC6F", "uniE93B", "uniE9D3","uniF8B5"};for (int i = 0; i < str.Length; i++){if (str[i] == name)return i;}return -1;
}private static List<FontGlyph> GetFontGlyphList(string fileName)
{List<FontGlyph> lst = GetXmlGlyf(fileName);for (int i = 0, len = lst.Count; i < len; i++){lst[i].Value = GetValue(lst[i].Name);}return lst;
}

7. 解密算法

private static string Decrypt(string str, List<FontGlyph> lstModel, List<FontGlyph> lstCur)
{string result = string.Empty;string[] ss = str.Split(new char[] {'.'});string[] ss1 = ss[0].Split(new char[] {';'}); //处理整数部分for (int i = 0; i < ss1.Length; i++){if (string.IsNullOrEmpty(ss1[i]) == false){int d = GetIndex(ss1[i], lstCur);int v = GetValue(lstCur[d].Glyph, lstModel);result += v.ToString();}}if (ss.Length != 1) //处理小数部分{result += ".";string[] ss2 = ss[1].Split(new char[] {';'});for (int i = 0; i < ss2.Length; i++){if (string.IsNullOrEmpty(ss2[i]) == false){int d = GetIndex(ss2[i], lstCur);int v = GetValue(lstCur[d].Glyph, lstModel);result += v.ToString();}}}return result;
}private static int GetIndex(string str, List<FontGlyph> lstCur)
{for (int i = 0, len = lstCur.Count; i < len; i++){if (lstCur[i].Name.Contains(str.Substring(3).ToUpper()))return i;}return -1;
}private static int GetValue(string str, List<FontGlyph> lstModel)
{for (int i = 0, len = lstModel.Count; i < len; i++){if (lstModel[i].Glyph == str){return lstModel[i].Value;}}return -1;
}

8. 获取「猫眼电影:国内票房榜 及对应影片信息」修改后的代码

public static List<Film> GetFilmsTicket()
{List<Film> result = new List<Film>();string url = "https://maoyan.com/board/1"; //国内票房榜IHtmlDocument doc = GetHtmlDocument(url);if (doc == null)return result;List<FontGlyph> lstModel = GetFontGlyphList(@".\font\base.xml");List<IHtmlElement> woffStr = doc.Find("style").ToList();string tempUrl = GetWoffUrl(woffStr[0].InnerHtml());string fileNameWoff = Download(tempUrl);string fileNameXml = TransXml(fileNameWoff);List<FontGlyph> lstNew = GetXmlGlyf(fileNameXml);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; //排名string dw, ticket;List<IHtmlElement> s;if (infor.Count < 5){item.Time = infor[1].InnerHtml().Trim().Remove(0, 5); //上映时间dw = infor[2].InnerHtml().Trim();dw = dw.Remove(0, dw.Length - 1); //实时票房单位s = infor[2].Find(".stonefont").ToList();ticket = s[0].InnerHtml().Trim(); //加密的实时票房item.BoxInfo = Decrypt(ticket, lstModel, lstNew) + dw; //实时票房dw = infor[3].InnerHtml().Trim();dw = dw.Remove(0, dw.Length - 1); //总票房单位s = infor[3].Find(".stonefont").ToList();ticket = s[0].InnerHtml().Trim(); //加密的总票房item.SumBoxInfo = Decrypt(ticket, lstModel, lstNew) + dw; //总票房}else{item.Actor = infor[1].InnerHtml().Trim().Remove(0, 3); //演员item.Time = infor[2].InnerHtml().Trim().Remove(0, 5); //上映时间dw = infor[3].InnerHtml().Trim();dw = dw.Remove(0, dw.Length - 1); //实时票房单位s = infor[3].Find(".stonefont").ToList();ticket = s[0].InnerHtml().Trim(); //加密的实时票房item.BoxInfo = Decrypt(ticket, lstModel, lstNew) + dw; //实时票房dw = infor[4].InnerHtml().Trim();dw = dw.Remove(0, dw.Length - 1); //总票房单位s = infor[4].Find(".stonefont").ToList();ticket = s[0].InnerHtml().Trim(); //加密的总票房item.SumBoxInfo = Decrypt(ticket, lstModel, lstNew) + dw; //总票房}IHtmlElement a = infor[0].Find("a").ToList()[0]; //获取影片urlitem.MovieName = 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;
}

9. 获取「猫眼电影:最受期待榜及对应影片信息」修改后的代码

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<FontGlyph> lstModel = GetFontGlyphList(@".\font\base.xml");List<IHtmlElement> woffStr = doc.Find("style").ToList();string tempUrl = GetWoffUrl(woffStr[0].InnerHtml());string fileNameWoff = Download(tempUrl);string fileNameXml = TransXml(fileNameWoff);List<FontGlyph> lstNew = GetXmlGlyf(fileNameXml);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 = Decrypt(people, lstModel, lstNew) + 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 = Decrypt(people, lstModel, lstNew) + dw; //解密的总想看人数IHtmlElement a = infor[0].Find("a").ToList()[0]; //获取影片urlitem.MovieName = 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;
}

10. 输出结果

猫眼电影:国内票房榜 及对应影片信息

猫眼电影:最受期待榜及对应影片信息


到此为止,有关如何破解猫眼电影的反爬虫机制就全部介绍完了,破解这种反爬虫机制相对来说比较复杂。如果网站通过用户请求的 Headers 进行反爬虫或者通过限制同一IP短时间内多次访问同一页面进行反爬虫,破解起来就相对容易很多,只要请求时加入相应的 Headers 信息或者利用代理IP绕过就好。今天就到这里吧,See You!


相关图文:

  • 如何利用 C# 爬取 One 持有者返利数据!
  • 如何利用 C# 爬取Gate.io交易所的公告!
  • 如何利用 C# 爬取BigOne交易所的公告!
  • 如何利用 C# 爬取 ONE 的交易数据?
  • 如何利用 C# 实现 K 最邻近算法?
  • 如何利用 C# 实现 K-D Tree 结构?
  • 如何利用 C# + KDTree 实现 K 最邻近算法?
  • 如何利用 C# 对神经网络模型进行抽象?
  • 如何利用 C# 实现神经网络的感知器模型?
  • 如何利用 C# 实现 Delta 学习规则?
  • 如何利用 C# 爬取「京东 - 计算机与互联网图书销量榜」!
  • 如何利用 C# 爬取「当当 - 计算机与互联网图书销量榜」!
  • 如何利用 C# 爬取「互动出版网 - 计算机图书销量榜」!
  • 如何利用 C# 爬取「中国图书网 - 计算机与互联网图书销量榜」!
  • 如何利用 C# 爬取带 Token 验证的网站数据?

如何利用 C# + Python 破解猫眼电影的反爬虫机制?相关推荐

  1. 用Python破解有道翻译反爬虫机制

    破解有道翻译反爬虫机制 web端的有道翻译,在之前是直接可以爬的.也就是说只要获取到了他的接口,你就可以肆无忌惮的使用他的接口进行翻译而不需要支付任何费用.那么自从有道翻译推出他的API服务的时候,就 ...

  2. Python(4) 用Python破解有道翻译反爬虫机制

    web端的有道翻译,在之前是直接可以爬的.也就是说只要获取到了他的接口,你就可以肆无忌惮的使用他的接口进行翻译而不需要支付任何费用.那么自从有道翻译推出他的API服务的时候,就对这个接口做一个反爬虫机 ...

  3. 从头学习爬虫(四十)高阶篇----模拟js生成Cookie中__jsl_clearance来破解加速乐的反爬虫机制

    本文主要提供中间模拟生成Cookie中__jsl_clearance字段来破解加速乐的反爬虫机制 前后通过postman模拟代替代码实现 一 需求 http://www.cyicai.com/info ...

  4. python破解网易反爬虫机制

    用python3 urllib破解有道翻译反爬虫机制 前言 最近在学习python 爬虫方面的知识,网上有一博客专栏专门写爬虫方面的,看到用urllib请求有道翻译接口获取翻译结果.发现接口变化很大, ...

  5. python爬虫与数据可视化(一)—— 爬取猫眼电影(涉及爬虫反破解)

    又是新的一年,让我们一起来看一下刚刚过去的2018留下了哪些经典影片吧! 一.获取电影详情页链接 进入猫眼官网,按图中的顺序点击,得到2018年按评分排序的影片进入猫眼官网,按图中的顺序点击,得到20 ...

  6. python爬猫眼电影正在热映的电影详情

    python爬猫眼电影正在热映的电影 这次咱们爬的是猫眼电影正在热映的电影. 网址:https://maoyan.com/ 以上图片中红色方框就是咱们要爬的内容,我们想要获取每部电影的详情页,我们首先 ...

  7. python爬猫眼电影影评,EX1 | 用Python爬取猫眼电影 APP 关于《无双》电影评论

    在本次推送中,以猫眼电影 APP 中的电影评论作为爬取目标,完成对网页数据的采集.在采集完成后,我们将每个评论数据采集分用户名.评论时间.用户性别.用户等级.用户所在城地.用户评分.以及评论内容等,并 ...

  8. 猫眼电影字体反爬-自动处理字体加密

    猫眼电影字体反爬 我们再爬取猫眼电影的时候,会遇到如下情况: 我们想要其中想看人数的数据,但是在网页源代码中并不是直接显示数字而是这一串东西. 这一串,其实是猫眼本身的一种字体,目的是不想每个人都获取 ...

  9. 手把手教你用Python搭建IP代理池,轻松破解请求频率限制反爬虫~

    我们所写的爬虫,它对服务器发出的网络请求频率要比正常用户的高的多,从而开发者可以将请求频率过高的用户视为爬虫程序,从而来限制爬虫程序. 今天志斌就来给大家分享一下,如何用Python搭建一个IP代理池 ...

最新文章

  1. centos6.5 安装mysql8,centos6上安装mysql8.0版本
  2. JavaScript语法详解(三)
  3. JZ2440用U-Boot给Nand-Flash烧写程序时报错:NAND write: incorrect device type in bootloader ‘bootloader‘ is not
  4. 学信网:研究生云复试平台快速搭建上线
  5. centec交换机配置_盛科(Centec)交换机 SmartConfig 特性
  6. php 自学提升进阶路线,瓶颈
  7. SecureCRT 8.5下载安装破解
  8. 读写锁就是恶霸和良民一起桑拿
  9. Echars 双击Legend 显示自己隐藏其他Legend
  10. 耀之阳电商:店铺运营的注意事项事项
  11. Hilt Test 短篇:插入辅助测试,插这插那,操家伙,看飞刀。——对面那位接着:memory 做的 *……()……*
  12. Xshell连接虚拟机linux
  13. 软件测试 | 测试开发 | 3年测试经验跳槽成功拿下30W+年薪
  14. 在vue项目中使用Antv-f2的小案例
  15. [047量化交易]python获取股票 量比 换手率 市盈率-动态 市净率 总市值 流通市值
  16. Oracle 12c 的安装
  17. 思科命令大全_【思唯网络学院】【汇总】思科网络设备产品型号大全!超全解释~...
  18. GDI/GDI+/D2D/D3D
  19. 把吃出来的病吃回去 张悟本_书籍:多活几十年:把吃出来的病吃回去
  20. 老闪创业那些事儿(84)——地面网络是怎么管理的

热门文章

  1. java中next的用法_关于java iterator的next()方法的用法
  2. bootstrap-less源码分析:容器
  3. c语言怎么创建一个h文件,求助C语言大佬 , 只会写到一个.c文件里 ,不会用.h头文件...
  4. leetcode--搜索插入位置--python
  5. Forefront for OCS2007之部署
  6. PHP中foreach详细解读
  7. 微软在慕尼黑设立欧洲首个物联网实验室
  8. 错误 1 “System.Data.DataRow.DataRow(System.Data.DataRowBuilder)”不可访问,因为它受保护级别限制...
  9. Ubuntu 12.10 拨号上网及停用方法
  10. init.rc的disabled含义