目前常见的Web反采集策略大概有以下几种:
- 1)数据加密;
- 2)限制访问频率;
- 3)数据以非文本形式展现;
- 4)验证码保护;
- 5)Cookie验证;
本文主要探讨一下如何突破“数据加密”:
反采集策略 - “数据加密”的原理:
- Web服务器端脚本将HTML文档中的部分数据加密,然后发送给HTTP客户端(浏览器)。
- 浏览器使用JavaScript将密文还原成文明后显示。
突破的方法:
根据JavaScrip解密算法源码,实现自己采集程序所需还原算法,在接收到服务器应答数据后,先对数据进行解密,然后再进行提取。
一个实例:
Whitepages的电话(手机)号码是这样输出的:
- <script type="text/javascript" > <br>
-
- document.write(WPOL.Util.rotDecode('(57) 1771 3775'));
-
- </script>
<script type="text/javascript" >
// <![CDATA[
document.write(WPOL.Util.rotDecode('(57) 1771 3775'));
// ]]>
</script>
在浏览器中看到的电话号码为:(02) 6226 8220,而不是”(57) 1771 3775“,如下所示:
在源码中可以找到WPOL.Util.rotDecode的源码如下:
- rotDecode: function(C) {
- var B, A = "";
- for (B = 0; B < C.length; B++) {
- var E = C.charAt(B);
- if (/[a-zA-Z]/.test(E)) {
- var D = /[A-Z]/.test(E) ? "A": "a";
- A += String.fromCharCode((E.charCodeAt(0) - D.charCodeAt(0) + 39) % 26 + D.charCodeAt(0))
- } else {
- if (/[0-9]/.test(E)) {
- A += String.fromCharCode((E.charCodeAt(0) - 48 + 15) % 10 + 48)
- } else {
- A += E
- }
- }
- }
- return A
rotDecode: function(C) {
var B, A = "";
for (B = 0; B < C.length; B++) {
var E = C.charAt(B);
if (/[a-zA-Z]/.test(E)) {
var D = /[A-Z]/.test(E) ? "A": "a";
A += String.fromCharCode((E.charCodeAt(0) - D.charCodeAt(0) + 39) % 26 + D.charCodeAt(0))
} else {
if (/[0-9]/.test(E)) {
A += String.fromCharCode((E.charCodeAt(0) - 48 + 15) % 10 + 48)
} else {
A += E
}
}
}
return A
我们的采集程序是采用Python编写的,所以需要根据上述代码实现我们自己的解密算法,如下:
- def phone_decode(phone_en):
-
-
- phone_de = ''
- for c in phone_en:
- if re.compile(r'[a-zA-Z]').search(c):
- if re.compile(r'[A-Z]').search(c):
- d = 'A'
- else:
- d = 'a'
- phone_de += chr((ord(c) - ord(d) + 39) % 26 + ord(d))
- else:
- if re.compile(r'[0-9]').search(c):
- phone_de += chr((ord(c) - 48 + 15) % 10 + 48)
- else:
- phone_de += c
- return phone_de
def phone_decode(phone_en):
"""Decode whitepages phone number
"""
phone_de = ''
for c in phone_en:
if re.compile(r'[a-zA-Z]').search(c):
if re.compile(r'[A-Z]').search(c):
d = 'A'
else:
d = 'a'
phone_de += chr((ord(c) - ord(d) + 39) % 26 + ord(d))
else:
if re.compile(r'[0-9]').search(c):
phone_de += chr((ord(c) - 48 + 15) % 10 + 48)
else:
phone_de += c
return phone_de
测试: