目前常見的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
測試: