爬蟲遇到字體動態加密?手把手破解

↑↑↑點擊上方「藍字」,關注極客猴html

若是你喜歡極客猴,能夠把我置頂加爲星標python


閱讀文本大概須要 6 分鐘。正則表達式

咱們在上一篇文章   《破解大衆點評的字體加密 中提到了,大衆點評只是靜態字體加密,此次咱們抱着學習的態度以貓眼電影爲例講講如何破解字體動態加密。

沒有了解過字體加密的小夥伴能夠先看看上一篇,本文與上一篇重複的部分就不細講了。微信

咱們打開貓眼電影票房榜單的首頁app

https://maoyan.com/board/1函數

很明顯,貓眼電影的榜單進行了字體加密。學習


讓咱們回憶一下破解大衆點評的步驟:
一、下載網站font字體包
二、將font字體包中導入FontEditor 觀察獲得亂碼與數字的關係
三、前綴替換,並將字體名字和它們所對應的亂碼構成一個字典
四、根據字典將加密的數字替換


然而,右鍵刷新頁面,字體文件一直在變:



爲了探究一下,咱們隨便下載3個字體文件,對比看看能不能發現其中的規律。


分別重命名爲A.woff,B.woff,C.woff,將他們依次導入FontEditor中打開



其中A字體的1對應的是【uniECC8】
       B字體的1對應的是【uniE5FD】
       C字體的1對應的是【uniEE6C】


並沒有規律。


咱們再將.woff文件轉換成.xml文件,看看字體結構有沒有類似之處:


#.woff文件轉換成.xml文件
from fontTools.ttLib import TTFont
font = TTFont('./.woff')
font.saveXML('A.xml')


每個編碼都對應一個TTGlyph對象,而許多行的XY座標點最終繪製成數字。



不少網上的教程到這裏就結束了,由於按理說這三個字體的統一數字對應的XY座標應是同樣的。


這說明貓眼最近又新挖了一個坑,繼續填坑。


看看上面的三個圖,其實他們的XY座標差別並不大。


因此咱們容許在必定範圍內的差別就算同樣就好啦。


因爲有負數,經過abs函數取絕對值


#對比兩個座標的差別
def compare(AA, BB):
    for i in range(5):
        if abs(AA[i][0] - BB[i][0]) < 80 and abs(AA[i][1] - BB[i][1]) < 80:
            pass
        else:
            return False
    return True
#True則可視爲是同一個字

這樣咱們就以某字體基準,不管如今實時的字體是哪個,只要下載下來,再與該字體進行座標差別對比,類似的就是同一數字。


在網上找了一張思路圖,方便你們理解:



咱們下面嘗試一下:
一、將新下載的字體文件與base_font對比,找到對應關係
二、前綴替換,並將字體名字和它們所對應的亂碼構成一個字典
三、根據字典將加密的數字替換


# 字體解密 
def modify_html(newFont, html):
    basefont = TTFont('./base_font.woff')
    unilist = newFont['cmap'].tables[0].ttFont.getGlyphOrder()
    numlist = []
    base_num = ['6''3''7''1''5''9''0''4''2''8']
    base_unicode = ['uniF0DA''uniE907''uniED01''uniEAE1''uniF206',
                   'uniE455''uniF401''uniE19C''uniEB76''uniF855']
    for i in range(1, len(unilist)):
        newGlyph = newFont['glyf'][unilist[i]].coordinates
        for j in range(len(base_unicode)):
            baseGlyph = basefont['glyf'][base_unicode[j]].coordinates
            if compare(newGlyph,baseGlyph):
                numlist.append(base_num[j])
                break
    rowList = []
    for i in unilist[2:]:
        i = i.replace('uni''&#x').lower() + ";"
        rowList.append(i)

    dictory = dict(zip(rowList, numlist))
    for key in dictory:
        if key in html:
            html = html.replace(key, str(dictory[key]))
    return html
# 返回解密後的html
四、利用正則表達式獲取數據
# 正則
def parse_page(html):
    pattern = re.compile('
  • .*?board-index-.*?>(.*?).*?src="(.*?)".*?'
                             + 'title="(.*?)".*?class="star">(.*?)字體


    .*?releasetime">(.*?)flex


    .*?'
                             + 'realtime".*?stonefont">(.*?).*?'
                             + 'total-boxoffice".*?stonefont">(.*?).*?網站


  • '

, re.S)


    items = re.findall(pattern, html)
    data = pd.DataFrame(items,columns=['index','image','title','star','releasetime','realtime','total-boxoffice'])
    data['star']=data['star'].str[3:]
    data['releasetime']=data['releasetime'].str[5:]
    print(data)
    return data


運行一下。



get。


本文相關爬蟲代碼,僅供學習交流:https://t.zsxq.com/RVn6qBU

END



精彩推薦
如何將 Pycharm 打造得更稱手
微軟也愛 Python!VS Code Python 全新發布!
受用一輩子的高效 PyCharm 使用技巧(六)



技術·思考·職場



長按二維碼,添加關注!

本文分享自微信公衆號 - 極客猴(Geek_monkey)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索