python 破解字体反爬 (二)
上一篇我介紹了破解58同城的字體反爬
https://blog.csdn.net/BigBoy_Coder/article/details/103239672
中間遺漏了幾個(gè)細(xì)節(jié),在這邊文章我做一下補(bǔ)充:
遺漏點(diǎn)一:
并不是所有的字體文件格式都是.ttf格式的文件,這里我們要針對原網(wǎng)頁的,進(jìn)行判斷
怎么判斷呢?
比如:https://su.58.com/qztech/?右鍵查看源碼,
我們發(fā)現(xiàn),文件的字體格式是woff形式的,所以這里我們把文件寫成.woff格式就好了?
那我們在進(jìn)入https://sz.58.com/chuzu/這個(gè)頁面。我們查看源碼
我們發(fā)現(xiàn),文件的字體格式是ttf形式的,所以這里我們把文件寫成.ttf格式就好了??
遺漏點(diǎn)二:
?上一篇文章我們是在cmap,獲取字符編碼的,但并不是所有的都是這樣,貓眼是把編碼對象在glyf?
所以我們還是要靈活的去分析xml文件,
遺漏點(diǎn)三:
當(dāng)我們看到字體文件,每個(gè)字可以看到字形和字形編碼。
觀察現(xiàn)在箭頭指的地方和前面箭頭指的地方的數(shù)字是不是一樣啊,沒錯(cuò),就是通過這種方法進(jìn)行映射的。
所以我們現(xiàn)在的思路似乎就是在源代碼里找到箭頭指的數(shù)字,然后再來字體里找到后替換就行了。
恭喜你,如果你也是這么想的,那你就掉坑里了。
因?yàn)槊看卧L問,字體字形是不變的,但字符的編碼確是變化的。因此,我們需要根據(jù)每次訪問,動態(tài)解析字體文件。
?
好了說完這兩個(gè)遺漏點(diǎn)之后,進(jìn)入到今天的主要內(nèi)容,手動構(gòu)建字體映射表:
由于 操作詳細(xì)步驟在上篇文章,都詳細(xì)做了介紹,在這篇文章只做分析過程
網(wǎng)頁地址:https://su.58.com/qztech/
步驟(1):打開網(wǎng)頁把字體文件保存下載,并且轉(zhuǎn)換成xml格式
FontCreator打開58.woff文件:
重復(fù)步驟一:
打開58_2.woff文件:
對比兩個(gè)文件,我們發(fā)現(xiàn)
? ?
?
因?yàn)槊看卧L問,字體字形是不變的,但字符的編碼確是變化的。因此,我們需要根據(jù)每次訪問,動態(tài)解析字體文件。
?到這里我們想通過寫死字體哪種方式是不行了:
分析一下兩個(gè)字體文件的對應(yīng)的xml文件,搜索 “技”,對應(yīng)的編碼:
xml的格式如下:
文件很長,我只截取了一部分。
仔細(xì)的觀察一下,你會發(fā)現(xiàn)~這倆下面的x,y,on值都是一毛一樣的。所以我們的思路就是以一個(gè)已知的字體文件為基本,然后將獲取到的新的字體文件的每個(gè)文字對應(yīng)的x,y,on值進(jìn)行比較,如果相同,那么說明新的文字對就 可以在基礎(chǔ)字體那里找到對應(yīng)的文字,有點(diǎn)繞,下面舉個(gè)小例子。
假設(shè): “我” 在基本字體中的名為uni1,對應(yīng)的x=1,y=1,n=1新的字體文件中,一個(gè)名為uni2對應(yīng)的x,y, n分別于上面的相等,那么這個(gè)時(shí)候就可以確定uni2 對應(yīng)的文字為”我”。
查資料的時(shí)候,發(fā)現(xiàn)在特殊情況下,有時(shí)候兩個(gè)字體中的文字對應(yīng)的x,y不相等,但是差距都是在某一個(gè)閾值之內(nèi),處理方法差不多,只不過上面是相等,這種情況下就是要比較一下。
分析到這我么就可一構(gòu)建字體映射表編寫代碼,爬取相關(guān)信息了
# coding=utf-8 import requests import re import time import lxml.html as H import base64 from fontTools.ttLib import TTFontdef get_data(url):headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',}session = requests.session()con = session.get(url, headers=headers)doc = H.document_fromstring(con.content)font_data_origin = re.search(r'base64,(.*?)\)', con.text, re.S).group(1)font_data_after_decode = base64.b64decode(font_data_origin)new_font_name = "font_new.woff"with open(new_font_name, 'wb') as f:f.write(font_data_after_decode)map_data = tff_parse(new_font_name)names = doc.xpath('//span[@class="infocardName fl stonefont resumeName"]/text()')# 有的時(shí)候會找不到,可以多執(zhí)行幾次;if names:for name in names:print('name in page source', name)for j in map_data.keys():name = name.replace(j, map_data[j])print ('name actual', name)def tff_parse(font_parse_name):# 我這里的字體的順序,如果你的不同,一定要修改font_dict = [u'博', u'經(jīng)', u'碩', u'屆', u'大', u'劉', u'8', u'1', u'士', u'E', u'2', u'6', u'張',u'M', u'驗(yàn)', u'5', u'本', u'趙', u'陳', u'吳', u'李', u'生', u'4', u'校', u'以', u'應(yīng)', u'黃',u'技', u'無', u'女', u'A', u'周', u'中', u'3', u'王', u'7', u'0', u'9', u'科', u'高', u'男',u'楊', u'專', u'下', u'B']font_base = TTFont('font_base.ttf')font_base_order = font_base.getGlyphOrder()[1:]# font_base.saveXML('font_base.xml') 調(diào)試用font_parse = TTFont(font_parse_name)# font_parse.saveXML('font_parse_2.xml')調(diào)試用font_parse_order = font_parse.getGlyphOrder()[1:]f_base_flag = []for i in font_base_order:flags = font_base['glyf'][i].flagsf_base_flag.append(list(flags))f_flag = []for i in font_parse_order:flags = font_parse['glyf'][i].flagsf_flag.append(list(flags))result_dict = {}for a, i in enumerate(f_base_flag):for b, j in enumerate(f_flag):if comp(i, j):key = font_parse_order[b].replace('uni', '')key = eval(r'u"\u' + str(key) + '"').lower()result_dict[key] = font_dict[a]return result_dictdef comp(L1, L2):if len(L1) != len(L2):return 0for i in range(len(L2)):if L1[i] == L2[i]:passelse:return 0return 1if __name__ == '__main__':url = "https://su.58.com/qztech/"get_data(url)反扒日系更新,以下兩篇文章,推薦看一看
https://www.freebuf.com/articles/web/206966.html
https://www.jianshu.com/p/4d28dd440cdd
?
總結(jié)
以上是生活随笔為你收集整理的python 破解字体反爬 (二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: yolo模型(四)绘制PR曲线所用到的r
- 下一篇: python勾股数_勾股数-随心随性无为