手把手找js加密代碼(鏈家地鐵找房--authorization)

通過鏈家的地鐵找房功能爬取地鐵線路以及小區(qū)數(shù)據(jù)時(shí),會(huì)碰到一個(gè)authorization參數(shù),這個(gè)參數(shù)每次請(qǐng)求都會(huì)變化,而且不帶也會(huì)請(qǐng)求失敗,因此可初步判斷是一個(gè)js加密參數(shù)。


第一次請(qǐng)求.png

第二次請(qǐng)求.png
我們通過chrome瀏覽器的斷點(diǎn)功能找authorization的加密js代碼

首先,抓包找到鏈接地址,點(diǎn)進(jìn)去


抓包找到j(luò)s文件.png

然后,格式化代碼并打上斷點(diǎn)


格式化代碼并打上斷點(diǎn).png

點(diǎn)擊地鐵路線,進(jìn)行網(wǎng)頁刷新
點(diǎn)擊旁邊的地鐵線路.png

Call Stack為函數(shù)框,Local為參數(shù)框,進(jìn)入debugger模式后,重點(diǎn)是找到加密函數(shù)所在位置,一般邏輯是看在某個(gè)函數(shù)之前,我們所找的參數(shù)不存在,那這個(gè)函數(shù)就是我們要找的(函數(shù)調(diào)用是從下到上)


函數(shù)與參數(shù)所在位置.png

最后一個(gè)函數(shù)為send,參數(shù)欄沒有發(fā)現(xiàn)authorization,但是我們?cè)赾onsole中把t打印出來,發(fā)現(xiàn)t中是包含了authorization的,因此需往前推繼續(xù)找加密函數(shù)
console輸出參數(shù).png

通過這樣往前遞歸查找,我們發(fā)現(xiàn)第二個(gè)ajax函數(shù)之后,就不再出現(xiàn)我們的authorization參數(shù)了,因此可定位authorization的加密代碼在第二個(gè)ajax里
加密代碼.png

同時(shí)發(fā)現(xiàn)ajax中存在l.authorization = s,var s = this.getMd5(l)兩行代碼,那么可確定authorization是被這個(gè)this.getMd5函數(shù)加密的了
點(diǎn)擊函數(shù).png

點(diǎn)擊進(jìn)入這個(gè)函數(shù),加上斷點(diǎn),并重新進(jìn)入debugger模式
加上斷點(diǎn)繼續(xù)運(yùn)行.png

可以看到輸入時(shí)一個(gè)字典,中間參數(shù)i是一個(gè)字符串,且i需要繼續(xù)被n函數(shù)處理


加上斷點(diǎn)重新運(yùn)行.png

進(jìn)入n函數(shù),發(fā)現(xiàn)是一系列的匿名函數(shù)與嵌套調(diào)用,繼續(xù)研究需要耗費(fèi)大量時(shí)間。我們仔細(xì)看一下n的名字,發(fā)現(xiàn)是md5加密,而python本身自帶md5加密庫,我們只需記錄js代碼的輸入與輸出,并與python的md5加密結(jié)果比對(duì)是否一致即可
n函數(shù).png

js中md5函數(shù)的輸入與輸出
js輸入與輸出.png

python中md5加密結(jié)果
python輸入與輸出.png

比較發(fā)現(xiàn)結(jié)果一致,再繼續(xù)運(yùn)行斷點(diǎn)到send,輸出t,發(fā)現(xiàn)參數(shù)與我們計(jì)算出的一致
t.png

理一下最終的代碼

import json
import time
import hashlib

import requests


# ------------------------------------------采集5號(hào)線所有站點(diǎn)的經(jīng)緯度--------------------------------------------------

def get_md5(txt):
    """md5加密函數(shù)"""
    
    m = hashlib.md5()
    m.update(txt.encode('utf-8'))
    return m.hexdigest()


def get_line_site(url):
    """請(qǐng)求鏈接"""
    
    headers = {'Accept': '*/*',
               'Accept-Encoding': 'gzip, deflate, br',
               'Accept-Language': 'zh-CN,zh;q=0.9',
               'Connection': 'keep-alive',
               'Host': 'ajax.lianjia.com',
               'Referer': 'https://gz.lianjia.com/ditu/',
               'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 '
                             '(KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'}
    r = requests.get(url, headers=headers)
    print(r.status_code)
    return r


def get_url():
    """拼接鏈接"""
    
    url = 'https://ajax.lianjia.com/map/subway/station/?city_id=440100&line_id=110460685&request_ts={' \
          'request_ts}&source=ljpc&authorization={authorization}'
    request_ts = int(time.time() * 1000)
    md5_data = "vfkpbin1ix2rb88gfjebs0f60cbvhedlcity_id=440100line_id=110460685request_ts={request_ts}".format(
        request_ts=request_ts)
    authorization = get_md5(md5_data)
    url = url.format(request_ts=request_ts, authorization=authorization)
    return url


if __name__ == '__main__':
    line_url = get_url()
    print(line_url)
    res = get_line_site(line_url)
    items = res.json()['data']
    with open('lon_and_lat.txt', 'w') as f:
        json.dump(items, f)

    print(items)

總結(jié)

1.多用斷點(diǎn)調(diào)試,調(diào)試時(shí)重點(diǎn)關(guān)注輸入、輸出以及一些特殊名字(比如rsa、md5、base64等常用加密)
2.到加密部分,搞清楚使用的是哪種加密方式,優(yōu)先使用python庫代替
3.了解常用的加密原理很重要

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容