图1-意淫爬虫与反爬虫间的对决
数据的重要性
如今已然是大数据时代,数据正在驱动着业务开发,驱动着运营手段,有了数据的支撑可以对用户进行用户画像,个性化定制,数据可以指明方案设计和决策优化方向,所以互联网产品的开发都是离不开对数据的收集和分析,数据收集的一种是方式是通过上报API进行自身平台用户交互情况的捕获,还有一种手段是通过开发爬虫程序,爬取竞品平台的数据,后面就重点说下爬虫的应用场景和实践中会遇到的问题和反反爬虫的一些套路与技巧。
应用场景
互联网平台,偏向销售公司,客户信息的爬取
资讯爬取并应用到平台业务中
竞品公司重要数据挖掘分析与应用
... ...
爬虫开发
爬虫必备技巧
做爬虫开发,需要对WEB这块有相对全面深入的理解,这样后面遇到反爬虫才能得心应手,见招拆招
了解HTML
了解CSS
了解JS
了解JSON
了解HTTP/HTTPS
会正则解析
会数据库操作
会使用抓包工具
浏览器F12开发者调试工具(推荐:谷歌),Network(网络)栏目可以获取抓包信息
工具:Charles,Fiddler (可抓包HTTPS,抓包APP)
通过抓包工具可以过滤出数据接口或者地址,并且分析请求信息和响应信息,定位数据所在的字段或者HTML标签
会使用开发者工具
浏览器F12开启开发者工具
需要会使用开发者工具调试HTML,CSS,JS
会模拟请求
能定位数据
数据在API中:前端/原生APP请求数据API,API返回数据大部分是JSON格式,然后渲染展示
数据在HTML中:查看页面HTML源代码,如果源代码里有想要获取的数据,就说明在服务端已经绑定好数据在HTML里
数据在JS代码中:查看页面HTML源代码,如果获取数据不在HTML里,又没有请求数据API,可以看下数据是不是绑定到JS变量里
会部署
反爬虫对抗技巧
反爬虫可以分为服务端限制 和前端限制
服务端限制 :服务器端行请求限制,防止爬虫进行数据请求
前端限制 :前端通过CSS和HTML标签进行干扰混淆关键数据,防止爬虫轻易获取数据
设置请求头(服务端限制 )
Referer
User-Agent
... ...
签名规则(服务端限制 )
延迟,或者随机延迟(服务端限制 )
代理IP(服务端限制 )
登录限制(服务端限制 )
验证码限制(服务端限制 )
CSS/HTML混淆干扰限制(前端限制 )
前端通过CSS或者HTML标签进行干扰混淆关键数据,破解需要抽样分析,找到规则,然后替换成正确的数据
1 . font-face,自定义字体干扰
如列子:汽车X家论帖子,猫X电影电影评分
<!--css--><!--找到://k3.autoimg.cn/g13/M05/D3/23/wKjByloAOg6AXB-hAADOwImCtp047..ttf--> <style>
@font-face {font-family: 'myfont';src: url('//k2.autoimg.cn/g13/M08/D5/DD/wKgH41oAOg6AMyIvAADPhhJcHCg43..eot');src: url('//k3.autoimg.cn/g13/M08/D5/DD/wKgH41oAOg6AMyIvAADPhhJcHCg43..eot?#iefix') format('embedded-opentype'),url('//k3.autoimg.cn/g13/M05/D3/23/wKjByloAOg6AXB-hAADOwImCtp047..ttf') format('woff');}</style><!--html--><!--会员招募中--><div> Mercedes C+ 会员招募<span style='font-family: myfont;'></span></div><!--
从html中获取【html中文编码】=
然后解析ttf文件得到【ttf中文编码】列表
匹配发现【ttf中文编码】=uniF159可以与【html中文编码】=匹配,在第7个,第7个中文就是"中"
(抽样分析会发现ttf中中文位置是固定的,中文编码是动态变化的,所以只要映射出【ttf中文编码】索引就可以知道中文字符了)
-->
破解思路: 找到ttf字体文件地址,然后下载下来,使用font解析模块包对ttf文件进行解析,可以解析出一个字体编码的集合,与dom里的文字编码进行映射,然后根据编码在ttf里的序号进行映射出中文
可以使用FontForge/FontCreator工具打开ttf文件进行分析
2 . 伪元素隐藏式
通过伪元素来显示重要数据内容 如例子:汽车X家
<!--css--><style>.hs_kw60_configod::before { content: "一汽";
}.hs_kw23_configod::before { content: "大众";
}.hs_kw26_configod::before { content: "奥迪";
}</style><!--html--><div>
<span class="hs_kw60_configod"></span>
- <span class="hs_kw23_configod"></span>
<span class="hs_kw26_configod"></span></div>
破解思路: 找到样式文件,然后根据HTML标签里class名称,匹配出CSS里对应class中content的内容进行替换
3 . backgroud-image
通过背景图片的position位置偏移量,显示数字/符号,如:价格,评分等 根据backgroud-postion值和图片数字进行映射
4 . html标签干扰
通过在重要数据的标签里加入一些有的没的隐藏内容的标签,干扰数据的获取 如例子:xxIP代理平台
<!--html--><td class="ip">
<p style="display:none;">2</p>
<span>2</span>
<span style="display:inline-block;"></span>
<div style="display: inline-block;">02</div>
<p style="display:none;">.1</p>
<span>.1</span>
<div style="display:inline-block;"></div>
<span style="display:inline-block;"></span>
<div style="display:inline-block;">09</div>
<span style="display: inline-block;">.</span>
<span style="display:inline-block;">23</span>
<p style="display:none;">7</p>
<span>7</span>
<p style="display:none;"></p>
<span></span>
<span style="display: inline-block;">.</span>
<div style="display: inline-block;"></div>
<p style="display:none;">3</p>
<span>3</span>
<div style="display: inline-block;">5</div>: <span class="port GEA">80</span></td><!--js--><script>
$(".ip:eq(0)>*:hidden").remove()
$(".ip:eq(0)").text()</script><!--
输出:202.109.237.35:80
通过移除干扰标签里有display:none隐藏标签,然后再获取text就不会有干扰的内容了
-->
破解思路: 过滤掉干扰混淆的HTML标签,或者只读取有效数据的HTML标签的内容
... ... (反爬虫脑洞有多大,反反爬虫拆招思路就有多淫 荡)
防止投毒
总结
目前大部分中小平台对防御爬虫的意识还比较薄弱,促使了爬虫的盛行,通过爬虫可以用比较小的代价,获取更大的利益
竞品数据的挖掘分析与应用对于业务增长有着举足轻重的作用,爬虫开发对于互联网产品公司的来说是个必不可少的技术
当前并没有一种可以完全避免爬虫的技术,所以添加反爬虫策略只是增加了一定的难度门槛,只要拆招技术够硬还是可以被突破翻越
反爬虫和反反爬虫是技术之间的较量,这场没有硝烟的战争永不停息。(程序员何必为难程序员)
供参考代码
font解析 C#和Python实现
/// 需要引入PresentationCore.dllprivate void Test() { string path = @"F:\font.ttf"; //读取字体文件
PrivateFontCollection pfc = new PrivateFontCollection();
pfc.AddFontFile(path); //实例化字体
Font f = new Font(pfc.Families[0], 16); //设置字体
txt_mw.Font = f; //遍历输出
var families = Fonts.GetFontFamilies(path); foreach (System.Windows.Media.FontFamily family in families) { var typefaces = family.GetTypefaces(); foreach (Typeface typeface in typefaces) {
GlyphTypeface glyph;
typeface.TryGetGlyphTypeface(out glyph);
IDictionary<int, ushort> characterMap = glyph.CharacterToGlyphMap; var datas = characterMap.OrderBy(d => d.Value).ToList(); foreach (KeyValuePair<int, ushort> kvp in datas) { var str = $"[{kvp.Value}][{kvp.Key}][{(char)kvp.Key}]\r\n";
txt_mw.AppendText(str);
}
}
}
}
# pip install TTFontfrom fontTools.ttLib import TTFontfrom fontTools.merge import *
me = Merger()
font = TTFont('./font.ttf')
cmaps = font.getBestCmap()
orders = font.getGlyphOrder()# font.saveXML('F:/1.xml')print cmapsprint orders
自我推荐
供参考资料
首发于本人独立博客
本文转自SFLYQ博客51CTO博客,如需转载,请自行联系原作者。
原文链接
------ End ------ |