爬蟲網(wǎng)絡請求之JS解密二(大眾點評)

- 前言

之前在做大眾點評網(wǎng)數(shù)據(jù)的時候切心,發(fā)現(xiàn)數(shù)據(jù)在前端顯示是用標簽來替換朽寞。這樣爬蟲采集到的就是一堆標簽加一點內容所混雜的臟數(shù)據(jù)挂洛,同時發(fā)現(xiàn)標簽中的值也是隨時改變的黎比。所以這次也是花了一點時間來整理關于大眾點評JS加密的內容超营,給大家簡單講解一下,以此來學習借鑒如何有效安全的防范爬蟲阅虫。僅供學習參考演闭,切勿用于商業(yè)用途

一、介紹

首先隨便打開大眾點評網(wǎng)一家店颓帝,看到數(shù)據(jù)都是正常狀態(tài)如圖1-1米碰,然后我們用開發(fā)者工具定位到元素上會發(fā)現(xiàn)如圖1-2所示:


圖1-1 正常數(shù)據(jù)顯示
圖1-2 獲取元素顯示

我們可以看到數(shù)據(jù)都是用<bb>標簽給替換了,同時我們還發(fā)現(xiàn)如圖1-3 购城、1-4所示:


圖1-3 電話號碼顯示

圖1-4 評論

店面基礎信息用<bb>標簽表示吕座、數(shù)字用<cc>表示、評論用<span>標簽表示瘪板。并且這些被替換的文字也不是固定的吴趴,可能過一會被替換的文字被還原,其余未被替換的文字被替換侮攀。而且標簽值也會隨時間發(fā)生改變锣枝,這樣即使每個標簽都人工標記,過一段時間數(shù)據(jù)還是會亂兰英。

二撇叁、頁面分析

我們隨便查看一個被替換了的標簽元素,發(fā)現(xiàn)它對應了一個文件如圖2-1所示:


圖2-1 替換的標簽所對應的鏈接

可以看到標簽一些基本信息畦贸,長度高度還有和它相關的一個鏈接陨闹,打開這個鏈接,我們可以發(fā)現(xiàn)是一個亂序的中文數(shù)據(jù)表格薄坏。如圖2-2所示:


圖2-2 被替換數(shù)據(jù)的表格

基本上我們就可以推測出來趋厉,數(shù)據(jù)被隱藏替換的大概原理,通過標簽來對應表格文字颤殴,其中class的值我們可以理解為被替換數(shù)據(jù)內容的key觅廓,標簽類型就好比對應的數(shù)據(jù)表,這里有三種類別標簽就是對應三張不同的數(shù)據(jù)表涵但,這樣我們還需要解決的問題是:
  • (1)不同種類的標簽如何對應不同的表杈绸;
  • (2)如何通過標簽的class值去對應被替換的數(shù)據(jù)帖蔓。
    所以到這一步,我們還少一些關鍵的線索瞳脓,我們繼續(xù)看到之前頁面塑娇,發(fā)現(xiàn)圖表鏈接包含在一個css表中 如圖2-3所示:


    圖2-3 隱藏的css文件

    可以看到有一個css文件,我們在元素中搜索這個表 如圖2-4


    圖2-4 css文件所在位置

    這樣我們便可以從網(wǎng)頁中找到指定的文件鏈接劫侧,關于如何根據(jù)key值找到對應的參照表埋酬。我們打開此鏈接如圖2-5、2-6所示:
    圖2-5 key值對照表
圖2-6key值對照表

我們可以從圖2-5烧栋、圖2-6看到cc標簽写妥、span標簽、bb標簽每個下面都有一個url审姓。我們打開可以發(fā)現(xiàn)就是之前那種格式的對應表珍特,我們稍后再看。我們先看到我們的key值(標簽class屬性對應的值)魔吐,后面都接著一個坐標扎筒,格式統(tǒng)一都是.(標簽class值){background: (橫坐標)px(縱坐標) px;這樣我們就已經獲得key值所對應的坐標,到這里我們基本可以確定酬姆,我們找到key值和所對應的坐標就可以根據(jù)標簽相對應的表嗜桌,利用坐標就可以找到利用標簽所替換的數(shù)據(jù)。

三辞色、JS解密

接下來骨宠,我們就需要知道如何利用獲取到的坐標來獲取正確被替換的數(shù)據(jù)。我們首先根據(jù)那張表格依次打開鏈接淫僻,查看它們元素會發(fā)現(xiàn)有兩種格式诱篷,一種格式有元素defs標簽,另一種沒有雳灵。如圖3-1棕所、圖3-2、圖3-3所示:


圖3-1 含有defs標簽格式數(shù)據(jù)表
圖3-2 無defs標簽格式數(shù)據(jù)表
圖3-3 含有defs標簽格式數(shù)據(jù)表

總共三張表對應三個不同標簽悯辙,分兩種格式琳省,我分成有defs標簽和無defs標簽兩類。注意躲撰,這里我并沒有根據(jù)標簽種類去劃分表類別针贬,因為每一次獲取到的格式都是隨機的。也就是說今天span標簽是對應有defs標簽數(shù)據(jù)表拢蛋,可能明天就對應不含有defs標簽類的數(shù)據(jù)表桦他。數(shù)據(jù)表格式是隨機變化的。

(1)含有defs標簽類別數(shù)據(jù)表解密

以地址中的bb標簽為例谆棱,看地址所對應的標簽值為pzgoz快压,如圖3-4所示:圆仔,以及bb標簽所對應的svg數(shù)據(jù)表,如圖3-6所示:


圖3-4 朝所對應標簽key

根據(jù)css表找到它的對應坐標x=-294,y=-113.0蔫劣,如圖3-5所示:


圖3-5 找到對應坐標

最后根據(jù)標簽類別找到對應svg數(shù)據(jù)表鏈接坪郭,打開鏈接,如圖3-6所示:
圖3-6 對應的svg數(shù)據(jù)表

將坐標轉為正脉幢,先從y坐標看到defs標簽d屬性上歪沃,y=113應該排序在d=M0 90 H600與d=M0 128 H600之間,所以id應該為4嫌松,再看textPath標簽xlink:href屬性為#4的就是我們所要找的行沪曙,如果之前有注意看標簽width的話,就知道每一個字長為14px豆瘫,x=294去除以14珊蟀,等于21,這一行做list的話外驱,list[21]應該就是朝字。代碼如下:

hight = html.xpath('//defs//path/@d')
      hight = [i.replace('M0','').replace('H600','').strip() for i in hight]
      hight.append(y)
      hight = sorted(hight, key=lambda i: int(i))
      y = hight.index(y)
      #若縱坐標與標簽y相等相等時腻窒,取同行的高度
      if y != len(hight) - 1 and hight[y] == hight[y + 1]:
          y = y + 1
      content = html.xpath('//textpath/text()')[y]
      content = ''.join(content).strip()
      x = int(int(x) / 14)
      return content[x]
(2)不含有defs標簽類別數(shù)據(jù)表解密

之前步驟一樣昵宇,直接跳到找到對應的svg數(shù)據(jù)表,如圖3-7所示:


圖3-7 不含有defs標簽類別數(shù)據(jù)表

比如數(shù)字3儿子,x=-232.0px y=-140.0px,先全部取正數(shù)瓦哎,y=140 對應在標簽text屬性y=118和y=163之間,同樣排序在第四位柔逼,所以取第四行為list蒋譬,同樣232/14=16,list[16]=3愉适;同時也可以數(shù)標簽text屬性x中232排在224-238之間犯助,也就是16-17位之間,但要取16為下標维咸。代碼如下:

hight = html.xpath('//text/@y')
        hight.append(y)
        hight = sorted(hight, key=lambda i: int(i))
        y = hight.index(y)
        # 若縱坐標與標簽y相等相等時剂买,取同行的高度
        if y != len(hight) - 1 and hight[y] == hight[y + 1]:
            y = y + 1
        content = html.xpath('//text/text()')[y]
        content = ''.join(content).strip()
        x = int(int(x) / 14)
        return content[x]

四、代碼實現(xiàn)

這里附上我測試的代碼癌蓖,僅供學習參考瞬哼,切勿用于商業(yè)用途。直接使用前租副,請帶上自己瀏覽器的請求頭參數(shù)坐慰。

#coding=utf-8
import requests
import lxml.html
import re
from decimal import Decimal
#獲取svg表格中被替換的數(shù)據(jù)
def get_hide_char(x,y,type,url):
    response = requests_middler(url)
    html = lxml.html.fromstring(response.content)
    #網(wǎng)頁格式是否有defs元素
    if len(html.xpath('//defs//path/@d'))<1:#如果沒有defs標簽
        hight = html.xpath('//text/@y')
        hight.append(y)
        hight = sorted(hight, key=lambda i: int(i))
        y = hight.index(y)
        # 若縱坐標與標簽y相等相等時,取同行的高度
        if y != len(hight) - 1 and hight[y] == hight[y + 1]:
            y = y + 1
        content = html.xpath('//text/text()')[y]
        content = ''.join(content).strip()
        x = int(int(x) / 14)
        return content[x]
    else:#如果含有defs標簽
        hight = html.xpath('//defs//path/@d')
        hight = [i.replace('M0','').replace('H600','').strip() for i in hight]
        hight.append(y)
        hight = sorted(hight, key=lambda i: int(i))
        y = hight.index(y)
        #若hight相等時用僧,取同行的高度
        if y != len(hight) - 1 and hight[y] == hight[y + 1]:
            y = y + 1
        content = html.xpath('//textpath/text()')[y]
        content = ''.join(content).strip()
        x = int(int(x) / 14)
        return content[x]

#請求url統(tǒng)一方式
def requests_middler(url):
    headers={'User-Agent':''}#加入自己的User-Agent
    html = requests.get(url, headers=headers)
    return html
#獲取css表中key值對應的坐標结胀,以及標簽對應svg表鏈接
def get_position_xy(html,password,type,url):
    #獲取key值對應的坐標
    rule = re.compile(password + '{background:-(.*?).0px -(.*?).0px;')
    result = re.findall(rule, html)[0]
    x = result[0]
    y = result[1]
    #獲取標簽所對應的svg表格
    rule = re.compile(type + '\[class\^="\w+"\]\{(.*?)}', re.S)
    result = re.findall(rule,html)[0]
    rule = re.compile('url\((.*?)\)')
    href = re.findall(rule, result)
    url = 'http:' + href[0]
    hide_char=get_hide_char(x,y,type,url)
    return hide_char

#解密前數(shù)據(jù)做好清洗两残,清洗成標簽與文字組成的list,保證還原字符串順序
def get_hide_string(s,url):
    result=[]
    a_list = re.split('</\S+>',s)
   # print(a_list)
    b=[]
    for i in a_list:
        try:
            dex = i.index('<')
        except ValueError:
            b.append(i)
            continue
        if dex!=0:
            b.append(i[:dex])
        rule = re.compile('<(.*?) class="(.*?)"')
        tag = re.findall(rule,i[dex:])[0]
        b.append(tag)
    try:
        b.remove('')
    except ValueError:
        pass
    print(b)#b為已清洗好的list把跨,接下來分別還原標簽替換數(shù)據(jù)
    html = requests_middler(url)
    html = html.text
    for tag in b:
        #遇到類別標簽則分類進行篩選
        if tag[0]=='span'or tag[0]== 'cc' or tag[0]=='bb':
            hide_char=get_position_xy(html,tag[1],tag[0],url)
            result.append(hide_char)
        #防止被其它標簽干擾
        elif tag[0]==''or tag[0]=='p'or tag[0]=='div':
            continue
        #遇到中文及不含標簽則直接加入list
        else:
            result.append(tag)
    return ''.join(result).strip('\n').strip()
if __name__=='__main__':
    url ='https://www.dianping.com/shop/507576/review_all'
    cookies={}#自己加入當時訪問的cookies
    headers = {'User-Agent': ''}#加入自己的User-Agent
    response=requests.get(url,headers=headers,cookies=cookies)
    html = lxml.html.fromstring(response.content)
    #找到標簽數(shù)據(jù)人弓,必須要保留標簽,這里以商店地址為例
    rule = re.compile('<div class="address-info">(.*?)</div>', re.S)
    address=re.findall(rule,response.text)[0]
    address = address.strip().replace('\n','').replace('&nbsp','')
    #找到css表着逐,css表鏈接存放位置固定崔赌,所以直接獲取
    css = html.xpath('//link[@rel="stylesheet"]/@href')[1]
    url ='http:'+css.strip()
    result = get_hide_string(address,url)
    result=result.replace(' ','')
    print('解密前數(shù)據(jù):'+address)
    print('解密后數(shù)據(jù):'+result)
代碼運行結果 如圖4-1所示:
圖4-1 運行結果圖
六、總結

總結一下耸别,就是先找到被替換數(shù)據(jù)標簽健芭,發(fā)現(xiàn)替換時對應的css表,找到css表秀姐,根據(jù)標簽屬性class值作key值去找到對應的坐標慈迈,同時找到標簽類別所對應的svg數(shù)據(jù)表鏈接,最后參照數(shù)據(jù)表坐標得到被隱藏的數(shù)據(jù)省有。
大眾點評前端JS加密方法與平時遇到的都不太一樣痒留,所以花了一些時間來講,之后遇到不一樣的JS加密也會給大家一起學習探討蠢沿,同樣如果發(fā)現(xiàn)文章的不足伸头,歡迎指出。

注意:由于大眾點評數(shù)據(jù)表和替換內容一直在變化舷蟀,所以你們看到的內容將可能與我寫的不一樣恤磷,但是原理和方法還是一樣。
如果您喜歡我的文章野宜,請關注或點擊喜歡扫步,您的支持是我最大的動力 ^ ^~!
僅供學習參考,切勿用于商業(yè)用途
轉載請注明作者及其出處

黑羊的皇冠 簡書主頁

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末匈子,一起剝皮案震驚了整個濱河市河胎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌旬牲,老刑警劉巖仿粹,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異原茅,居然都是意外死亡吭历,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門擂橘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來晌区,“玉大人,你說我怎么就攤上這事±嗜簦” “怎么了恼五?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長哭懈。 經常有香客問我灾馒,道長,這世上最難降的妖魔是什么遣总? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任睬罗,我火速辦了婚禮,結果婚禮上旭斥,老公的妹妹穿的比我還像新娘容达。我一直安慰自己,他們只是感情好垂券,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布花盐。 她就那樣靜靜地躺著,像睡著了一般菇爪。 火紅的嫁衣襯著肌膚如雪算芯。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天娄帖,我揣著相機與錄音也祠,去河邊找鬼。 笑死近速,一個胖子當著我的面吹牛,可吹牛的內容都是我干的堪旧。 我是一名探鬼主播削葱,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼淳梦!你這毒婦竟也來了析砸?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤爆袍,失蹤者是張志新(化名)和其女友劉穎首繁,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體陨囊,經...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡弦疮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了蜘醋。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胁塞。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出啸罢,到底是詐尸還是另有隱情编检,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布扰才,位于F島的核電站允懂,受9級特大地震影響,放射性物質發(fā)生泄漏衩匣。R本人自食惡果不足惜蕾总,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望舵揭。 院中可真熱鬧谤专,春花似錦、人聲如沸午绳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拦焚。三九已至蜡坊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間赎败,已是汗流浹背秕衙。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留僵刮,地道東北人据忘。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像搞糕,于是被迫代替她去往敵國和親勇吊。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內容

  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5窍仰? 答:HTML5是最新的HTML標準汉规。 注意:講述HT...
    kismetajun閱讀 27,486評論 1 45
  • ORA-00001: 違反唯一約束條件 (.) 錯誤說明:當在唯一索引所對應的列上鍵入重復值時,會觸發(fā)此異常驹吮。 O...
    我想起個好名字閱讀 5,320評論 0 9
  • HTML標簽解釋大全 一针史、HTML標記 標簽:!DOCTYPE 說明:指定了 HTML 文檔遵循的文檔類型定義(D...
    米塔塔閱讀 3,247評論 1 41
  • EXCEL小白的進階之路 從16年3月申請的小號,到現(xiàn)在發(fā)表的微文碟狞,屈指可數(shù)啄枕,糾結于想要好的內容,好的頁面排版篷就,然...
    Rachelhaha閱讀 950評論 0 0
  • 暑假剛過,前段時間智润,一篇熱文刷爆了朋友圈《中產階級的焦慮:月薪三萬撐不起孩子的一個暑假》及舍,這篇文章說的是一個中產階...
    紙匠情挑閱讀 662評論 0 4