Python爬蟲雜記 - 字體文件反爬(二)

字體文件反爬

在搞定靜態(tài)字庫反爬之后, 可以解決部分字體文件的反爬, 但動態(tài)字文件反爬是解決不掉的。此文章就是為解決動態(tài)字體文件的反反爬而寫。本想以去哪兒網(wǎng)(手機(jī)端)的為例, 奈何手機(jī)端的字庫反爬可能需要賬號密碼才會出現(xiàn), 遂改用貓眼電影網(wǎng)的字體文件反爬為例。源碼在最后!

1. 開發(fā)者模式查看網(wǎng)頁內(nèi)容

開發(fā)者模式中的字體無法顯示

2. 下載網(wǎng)頁源碼保存至本地查看

網(wǎng)頁源碼下載到本地后查看

3. 字體文件保存在本地通過 font creator 查看字體文件信息

字體文件1
字體文件2

可以查看到字體文件的映射關(guān)系是動態(tài)的, 需要解決的就是通過某種方法來找到映射與數(shù)字之間的關(guān)系。

4.通過fontTools庫, 將字庫文件轉(zhuǎn)換成xml格式

映射關(guān)系與字體信息
# 將字體文件轉(zhuǎn)換成xml格式可以發(fā)現(xiàn)字體保存的圖行信息是不變的, 變化的是unicode映射
#以此為突破點, 找到圖形對應(yīng)的編碼, 然后再匹配到對應(yīng)的數(shù)字,以不變應(yīng)萬變。
onlineFonts = TTFont('fonts.woff')
onlineFonts.saveXML('test.xml')
注: 此步驟在實際生產(chǎn)過程中并不需要, 為了便于理解, 我加上了 

5.通過fontTools庫, 獲取字體信息中不變的部分

baseFonts = TTFont('basefonts.woff') # basefonts.woff 這個文件是保存在本地的, 需要手動解析一個字體庫, 作為不變的部分
base_nums = ['7', '9', '0', '3', '6', '5', '2', '1', '4', '8'] # 基本的數(shù)字表
base_fonts = ['uniF04C', 'uniE374', 'uniF426', 'uniEAAA', 'uniF519', 'uniEEC4', 'uniF543', 'uniF7C7', 'uniF046',
          'uniF08E'] # 基本的映射表 
onlineFonts = TTFont('fonts.woff') # 網(wǎng)絡(luò)上下載的動態(tài)的字體文件
uni_list = onlineFonts.getGlyphNames()[1:-1] # 只有中間的部分是數(shù)字
temp = {}
# 解析字體庫
for i in range(10):
    onlineGlyph = onlineFonts['glyf'][uni_list[i]]  # 返回的是unicode對應(yīng)信息的對象
    for j in range(10):
        baseGlyph = baseFonts['glyf'][base_fonts[j]]
        if onlineGlyph == baseGlyph:
            temp["&#x" + uni_list[i][3:].lower() + ';'] = base_nums[j]

6.最終結(jié)果展示

最終結(jié)果

參考資料:
知乎作者謝俊杰的文章
fontTools庫詳解
github fonttools庫詳解

本人水平有限, 如有錯誤歡迎提出指正!如有參考, 請注明出處!!禁止抄襲,遇抄必肛!!!

源碼:

# coding:utf-8

import re
import requests
from fontTools.ttLib import TTFont
from lxml import etree

headers = {
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) "
              "Chrome/66.0.3359.139 Safari/537.36 "
    }

index_url = 'http://maoyan.com/'
# 獲取首頁內(nèi)容
response_index = requests.get(index_url, headers=headers).text
index_xml = etree.HTML(response_index)
info_list = index_xml.xpath('//*[@id="app"]/div/div[1]/div[1]/div/div[2]/ul/li[1]/a/div[2]/div//text()')
a = u'電影名稱:%s, 票房總數(shù):%s' % (info_list[1], info_list[4])
print (a)

# 獲取字體文件的url
woff_ = re.search(r"url\('(.*\.woff)'\)", response_index).group(1)
woff_url = 'http:' + woff_
response_woff = requests.get(woff_url, headers=headers).content

with open('fonts.woff', 'wb') as f:
    f.write(response_woff)

#base_nums, base_fonts 需要自己手動解析映射關(guān)系, 要和basefonts.woff一致
baseFonts = TTFont('basefonts.woff')
base_nums = ['7', '9', '0', '3', '6', '5', '2', '1', '4', '8']
base_fonts = ['uniF04C', 'uniE374', 'uniF426', 'uniEAAA', 'uniF519', 'uniEEC4', 'uniF543', 'uniF7C7', 'uniF046',
              'uniF08E']
onlineFonts = TTFont('fonts.woff')

# onlineFonts.saveXML('test.xml')

uni_list = onlineFonts.getGlyphNames()[1:-1]
temp = {}
# 解析字體庫
for i in range(10):
    onlineGlyph = onlineFonts['glyf'][uni_list[i]]
    for j in range(10):
        baseGlyph = baseFonts['glyf'][base_fonts[j]]
        if onlineGlyph == baseGlyph:
            temp["&#x" + uni_list[i][3:].lower() + ';'] = base_nums[j]

# 字符替換
pat = '(' + '|'.join(temp.keys()) + ')'
response_index = re.sub(pat, lambda x: temp[x.group()],     response_index)

# 內(nèi)容提取
index_xml = etree.HTML(response_index)
info_list = index_xml.xpath('//*[@id="app"]/div/div[1]/div[1]        /div/div[2]/ul/li[1]/a/div[2]/div//text()')
a = u'電影名稱:%s, 票房總數(shù):%s' % (info_list[1], info_list[4])
print(a)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,076評論 25 708
  • ttf 文件反爬 想寫這篇文章的起源是在一個技術(shù)群里,有人討論去哪網(wǎng)(手機(jī)端)的反爬:請求下來的數(shù)字跟瀏覽器上的數(shù)...
    董小賤閱讀 12,222評論 18 15
  • 我不知風(fēng)從哪個方向吹來, 送來了一股久違的花香, 我在夢中沉醉。 沉醉著,沉醉著, 香味愈來愈淡, 欲隨花香而去,...
    憶思寒閱讀 223評論 0 1
  • 當(dāng)那道黑色光影出現(xiàn)時,天地間的靈氣仿佛都是咆哮暴動,一種連天地都為之顫粟的威壓彌漫開來。在那種威壓之下,這里所有人...
    混沌天書閱讀 954評論 0 0
  • 多數(shù)情況下,一個人損害另一個人,是出于迫不得已,一個人要發(fā)跡,沒有現(xiàn)成的道路可以走,必然要踩到別人 要想不這么死,...
    jesmil閱讀 668評論 0 1