應對js反爬蟲的嘗試姑曙,爬取中國人民銀行

在 - 簡書-爬蟲數(shù)據(jù)分析學習交流 - 微信群里有位朋友Jacky提到爬取中國銀行遇到的問題,一時興起便做了嘗試迈倍。


  • 首先還原問題伤靠,我們禁用js,在chrome瀏覽器中新建標簽頁啼染,F(xiàn)12 > F1 >打開設(shè)置在右下角找到禁用js并勾選


  • 打開中國人民銀行條法司網(wǎng)頁發(fā)現(xiàn)如下的頁面顯示
  • 然后F12關(guān)閉開發(fā)者控制臺宴合,刷新頁面,顯示正常


  • 利用chrome插件迹鹅,EditThisCookie卦洽,在控制臺中查看cookie如下,同時禁用js再次打開網(wǎng)頁卻發(fā)現(xiàn)顯示正常斜棚,而清空cookie(禁用js)后打開又出現(xiàn)問題顯示阀蒂。
  • 這是因為該網(wǎng)頁首先傳給你的html文件中包含cookie設(shè)置和動態(tài)跳轉(zhuǎn)網(wǎng)址的js代碼该窗,js代碼運行后會自動設(shè)置cookie并跳轉(zhuǎn)鏈接,到達正常頁面蚤霞。
  • 我們查看問題頁面的源碼酗失,Ctrl-U


    Paste_Image.png
  • 源碼很亂,以我的菜雞水平根本看不出來什么東西昧绣,這時需要優(yōu)秀工具的幫助规肴,http://jsbeautifier.org/ 是一款優(yōu)秀js代碼美化和解析工具,我們將代碼放上去解析夜畴,終端curl網(wǎng)頁得到的js代碼和解析后的代碼對比鮮明
  • 與一般的代碼美化工具比較(下圖)奏纪,不僅格式化了代碼,并且可讀化了代碼斩启,這樣以我的水平就可以分析代碼了序调。


  • 首先兩次請求該網(wǎng)址,將兩次美化后的代碼進行對比兔簇,我們可以看到不僅在js全局變量上有改變发绢,在其中一個加密函數(shù)里也有小改動。



  • 某一個請求里的js代碼垄琐,留存參考边酒,閱讀可先跳過:
var dynamicurl = "/L3RpYW9mYXNpLzE0NDk0MS8xNDQ5NTcvaW5kZXguaHRtbA==";
var wzwschallenge = "RANDOMSTR14925";
var wzwschallengex = "STRRANDOM14925";
var template = 4;
var encoderchars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

function KTKY2RBD9NHPBCIHV9ZMEQQDARSLVFDU(str) {
    var out, i, len;
    var c1, c2, c3;
    len = str.length;
    i = 0;
    out = "";
    while (i < len) {
        c1 = str.charCodeAt(i++) & 0xff;
        if (i == len) {
            out += encoderchars.charAt(c1 >> 2);
            out += encoderchars.charAt((c1 & 0x3) << 4);
            out += "==";
            break;
        }
        c2 = str.charCodeAt(i++);
        if (i == len) {
            out += encoderchars.charAt(c1 >> 2);
            out += encoderchars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xf0) >> 4));
            out += encoderchars.charAt((c2 & 0xf) << 2);
            out += "=";
            break;
        }
        c3 = str.charCodeAt(i++);
        out += encoderchars.charAt(c1 >> 2);
        out += encoderchars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xf0) >> 4));
        out += encoderchars.charAt(((c2 & 0xf) << 2) | ((c3 & 0xc0) >> 6));
        out += encoderchars.charAt(c3 & 0x3f);
    }
    return out;
}

function findDimensions() {
    var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
    var h = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
    if (w * h <= 120000) {
        return true;
    }
    var x = window.screenX;
    var y = window.screenY;
    if (x + w <= 0 || y + h <= 0 || x >= window.screen.width || y >= window.screen.height) {
        return true;
    }
    return false;
}

function QWERTASDFGXYSF() {
    var tmp = wzwschallenge + wzwschallengex;
    var hash = 0;
    var i = 0;
    for (i = 0; i < tmp.length; i++) {
        hash += tmp.charCodeAt(i);
    }
    hash *= 11;
    hash += 111111;
    return "WZWS_CONFIRM_PREFIX_LABEL4" + hash;
}

function HXXTTKKLLPPP5() {
    if (findDimensions()) {} else {
        var cookieString = "";
        cookieString = "wzwstemplate=" + KTKY2RBD9NHPBCIHV9ZMEQQDARSLVFDU(template.toString()) + "; path=/";
        document.cookie = cookieString;
        var confirm = QWERTASDFGXYSF();
        cookieString = "wzwschallenge=" + KTKY2RBD9NHPBCIHV9ZMEQQDARSLVFDU(confirm.toString()) + "; path=/";
        document.cookie = cookieString;
        window.location = dynamicurl;
    }
}
HXXTTKKLLPPP5();
  • 這種程度的js代碼(美化后)并不難理解,很明顯可以看出最后的函數(shù)調(diào)用中利用document.cookie設(shè)置了兩個cookie狸窘,并利用window.location設(shè)置了跳轉(zhuǎn)網(wǎng)址墩朦,靜下心去分析也能用python寫出相應的加密程序,用正則取配到變量翻擒,生成我們想要的信息氓涣,但是有沒有更快的方法呢。這時我們又有一個強大的工具陋气,Js2Py劳吠,利用它我們可以解析js代碼變?yōu)閜ython中的可執(zhí)行代碼。如下官方簡單示例:
  • 下面的思路就清晰了巩趁,先利用js美化工具的python庫jsbeautifier(pip安裝)美化代碼痒玩,然后不管js代碼中關(guān)于dom操作的內(nèi)容(如window.xx),取出js全局變量和加密函數(shù)议慰,利用js2py生成可執(zhí)行的python函數(shù)蠢古,以js代碼中的主干邏輯在python里執(zhí)行獲得cookies,在requests.session中更新cookies并訪問js變量中的動態(tài)網(wǎng)址别凹,就可以成功到達內(nèi)容頁草讶,開始爬取解析了。
  • 以下為python代碼番川,可以看到最后成功驗證我們爬取到了有效信息到涂。
import requests
import re
import jsbeautifier
import js2py

host_url = 'http://www.pbc.gov.cn/'
dest_url = 'http://www.pbc.gov.cn/tiaofasi/144941/144957/index.html'
# 利用session保存cookie信息,第一次請求會設(shè)置cookie類似{'wzwsconfirm': 'ab3039756ba3ee041f7e68f634d28882', 'wzwsvtime': '1488938461'}颁督,與js解析得到的cookie合起來才能通過驗證
r = requests.session()
content = r.get(dest_url).content
# 獲取頁面腳本內(nèi)容
re_script = re.search(r'<script type="text/javascript">(?P<script>.*)</script>', content.decode('utf-8'), flags=re.DOTALL)
# 用點匹配所有字符践啄,用(?P<name>...)獲取:https://docs.python.org/3/howto/regex.html#regex-howto
# cheatsheet:https://github.com/tartley/python-regex-cheatsheet/blob/master/cheatsheet.rst
script = re_script.group('script')
script = script.replace('\r\n', '')
# 在美化之前沉御,去掉\r\n之類的字符才有更好的效果
res = jsbeautifier.beautify(script)
# 美化并一定程度解析js代碼:https://github.com/beautify-web/js-beautify
with open('x.js','w') as f:
    f.write(res)
# 寫入文檔進行查看分析

jscode_list = res.split('function')
var_ = jscode_list[0]
var_list = var_.split('\n')
template_js = var_list[3] # 依順序獲取屿讽,亦可用正則
template_py = js2py.eval_js(template_js)
# 將所有全局變量插入第一個函數(shù)變?yōu)榫植孔兞坎⒂嬎?function1_js = 'function' + jscode_list[1]
position = function1_js.index('{') +1
function1_js = function1_js[:position]+ var_ +function1_js[position:]
function1_py = js2py.eval_js(function1_js)
cookie1 = function1_py(str(template_py)) # 結(jié)果類似'NA=='
# 保存得到的第一個cookie
cookies = {}
cookies['wzwstemplate'] = cookie1
# 對第三個函數(shù)做類似操作
function3_js = 'function' + jscode_list[3]
position = function3_js.index('{') +1
function3_js = function3_js[:position]+ var_ +function3_js[position:]
function3_py = js2py.eval_js(function3_js)
middle_var = function3_py() # 是一個str變量,結(jié)果類似'WZWS_CONFIRM_PREFIX_LABEL4132209'
cookie2 = function1_py(middle_var)
cookies['wzwschallenge'] = cookie2
# 關(guān)于js代碼中的document.cookie參見 https://developer.mozilla.org/zh-CN/docs/Web/API/Document/cookie
dynamicurl = js2py.eval_js(var_list[0])

# 利用新的cookie對提供的動態(tài)網(wǎng)址進行訪問即是我們要達到的內(nèi)容頁面了
r.cookies.update(cookies)
content = r.get(host_url+dynamicurl).content

# 最后驗證是否爬取到有效信息
if u'銀行卡清算機構(gòu)管理辦法' in content.decode('utf-8'):
    print('success')
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末吠裆,一起剝皮案震驚了整個濱河市伐谈,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌试疙,老刑警劉巖诵棵,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異祝旷,居然都是意外死亡履澳,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門怀跛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來距贷,“玉大人,你說我怎么就攤上這事吻谋≈一龋” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵漓拾,是天一觀的道長阁最。 經(jīng)常有香客問我,道長骇两,這世上最難降的妖魔是什么闽撤? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮脯颜,結(jié)果婚禮上哟旗,老公的妹妹穿的比我還像新娘。我一直安慰自己栋操,他們只是感情好闸餐,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著矾芙,像睡著了一般舍沙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上剔宪,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天拂铡,我揣著相機與錄音壹无,去河邊找鬼。 笑死感帅,一個胖子當著我的面吹牛斗锭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播失球,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼岖是,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了实苞?” 一聲冷哼從身側(cè)響起豺撑,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎黔牵,沒想到半個月后聪轿,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡猾浦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年屹电,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片跃巡。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡危号,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出素邪,到底是詐尸還是另有隱情外莲,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布兔朦,位于F島的核電站偷线,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏沽甥。R本人自食惡果不足惜声邦,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望摆舟。 院中可真熱鬧亥曹,春花似錦、人聲如沸恨诱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽照宝。三九已至蛇受,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間厕鹃,已是汗流浹背兢仰。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工乍丈, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人把将。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓轻专,卻偏偏與公主長得像,于是被迫代替她去往敵國和親秸弛。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 前端開發(fā)者丨h(huán)ttp請求 https:www.rokub.com 前言見解有限洪碳, 如有描述不當之處递览, 請幫忙指出,...
    麋鹿_720a閱讀 10,896評論 11 31
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,742評論 25 707
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理瞳腌,服務(wù)發(fā)現(xiàn)绞铃,斷路器,智...
    卡卡羅2017閱讀 134,628評論 18 139
  • “嗯”女孩沒有太糾結(jié)這個問題嫂侍,“你累了吧儿捧?” “不累!”男孩沒有騙人挑宠,他真得不累菲盾,有女孩在身邊,他從來都不累各淀,不熱...
    垚君閱讀 197評論 0 0
  • 早前有讀過胡蘭成的《禪是一枝花》懒鉴,不由的覺得這確是一本難得的好書。我向很多朋友都推薦過這本書碎浇。我自己對書中幾則公案...
    振之閱讀 373評論 0 2