貓眼電影的字體加密還是很折磨人的(最后會附上源碼讶坯,中間講解部分就用截圖代替)
準(zhǔn)備部分
貓眼電影主要在于字體加密遣钳,如何破解像云?需要準(zhǔn)備點(diǎn)東西:FontCreator,這是一個軟件税迷,下載即可境肾。
開始分析了~剔难,我們以這個為例:https://maoyan.com/films/1209159。
解析字體當(dāng)然需要當(dāng)前網(wǎng)頁的字體奥喻,查看網(wǎng)頁源碼偶宫,找到網(wǎng)頁字體 1-1
將字體下載下來,然后刷新頁面环鲤,會發(fā)現(xiàn)字體改變了 1-2
沒關(guān)系纯趋,再下載一次,現(xiàn)在有兩個本頁面的woff文件 1-3冷离,要進(jìn)入重點(diǎn)了
分析部分
首先要將下載好的woff文件換個格式 2-1吵冒、2-2
將兩個保存好的xml文件打開備用 2-3
然后用FontCreator打開我們的兩個woff文件 2-4
現(xiàn)在對應(yīng)關(guān)系已經(jīng)很明了了,我們以4為例:兩個woff文件的4分別對應(yīng)uniE88A西剥、uniE325痹栖,然后我們在對應(yīng)的xml文件中找到它們 2-5、2-6
pt里面的數(shù)據(jù)是一樣蔫耽,說明我們的字體映射關(guān)系找對了结耀,下面就需要設(shè)置對應(yīng)的映射關(guān)系了
測試部分
我們先把其中一個woff文件中的對應(yīng)映射打印出來看一下 3-1留夜、3-2
和我們的xml中的關(guān)系對應(yīng) 3-3
然后我們根據(jù)FontCreator中的數(shù)據(jù)設(shè)置對應(yīng)的映射關(guān)系 3-4
輸出一下匙铡,關(guān)系正確 3-5
對應(yīng)關(guān)系已經(jīng)找到图甜,現(xiàn)在看看網(wǎng)頁源碼,發(fā)現(xiàn)源碼中的加密字體都是由&#x開頭 3-6
這個不用擔(dān)心鳖眼,因?yàn)槲覀冎恍枰?amp;#x替換成uni就行了黑毅,關(guān)系就會一一對應(yīng),然后就可以返回正確的數(shù)據(jù)了钦讳。
結(jié)果
下面開始源碼和測試結(jié)果
import requests
import re
import os
from fontTools.ttLib import TTFont
class MaoYan():
????#初始化需要的數(shù)據(jù)
? ? def __init__(self):
????????self.url ='http://maoyan.com/films/1209159'
? ? ? ? self.headers = {
????????????"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, ????????????like Gecko) Chrome/70.0.3538.110 Safari/537.36",
????????}
????# 發(fā)送請求
? ? def get_html(self, url):
????????response = requests.get(url,headers=self.headers)
????????return response.content
????#下載woff字體文件
? ? def create_font(self, font_file):
????????# 列出已下載文件
? ? ? ? file_list = os.listdir('./fonts')
????????# 判斷是否已下載
? ? ? ? if font_file not in file_list:
????????????# 未下載則下載新woff字體文件
? ? ? ? ? ? url ='http://vfile.meituan.net/colorstone/' + font_file
????????????new_file =self.get_html(url)
????????????with open('./fonts/' + font_file,'wb')as f:
????????????????f.write(new_file)
????????# 打開字體文件
? ? ? ? self.font = TTFont('./fonts/' + font_file)
????# 把獲取到的數(shù)據(jù)用字體對應(yīng)起來矿瘦,得到真實(shí)數(shù)據(jù)
? ? def modify_data(self, data):
????????#打開自己保存的woff文件,設(shè)置映射關(guān)系
? ? ? ? font2 = TTFont("./95ebcb3e871c993e8014b6cf244c939b2088.woff")
????????keys = font2['glyf'].keys()
????????values =list(' .0714682953')
????????#對應(yīng)替換
? ? ? ? dict1 =dict((k, v)for k, v in zip(keys, values))
????????font1 =self.font
????????#空字典愿卒,保存新的替換映射關(guān)系
? ? ? ? dict2 = {}
????????for key in font1["glyf"].keys():
????????????for k, v in dict1.items():
????????????????# 通過比較 字形定義 填充新的name和num映射關(guān)系
? ? ? ? ? ? ? ? if font2["glyf"][k] == font1["glyf"][key]:
????????????????????dict2[key] = v.strip()
????????????????????break
? ? ? ? #將獲取到的網(wǎng)頁數(shù)據(jù)中的&#x替換成uni
? ? ? ? for i in dict2:
????????????gly = i.replace('uni','&#x').lower() +';'
? ? ? ? ? ? if gly in data:
????????????????data = data.replace(gly, dict2[i])
????????return data
????#獲取數(shù)據(jù)
? ? def start_crawl(self):
????????html =self.get_html(self.url).decode('utf-8')
????????# 正則匹配字體文件
? ? ? ? font_file = re.findall(r'vfile\.meituan\.net\/colorstone\/(\w+\.woff)', html)[0]
????????self.create_font(font_file)
????????# 正則匹配評分
? ? ? ? star = re.findall(r'<span class="index-left info-num ">\s+<span class="stonefont">(.*?)</span>\s+</span>', html)[0]
????????star =self.modify_data(star)
????????# 正則匹配想看的人數(shù)
? ? ? ? people = re.findall(r'<span class=".*?score-num.*?">(.*?)</span>', html,re.S)[0]
????????people =self.modify_data(people)
????????# 正則匹配累計票房
? ? ? ? ticket_number = re.findall(r'<div class="movie-index-content box">\s+<span class="stonefont">(.*?)</span><span class="unit">(.*?)</span>\s+</div>', html)[0]
????????ticket_number1 =self.modify_data(ticket_number[0])
????????print('用戶評分: %s' % star)
????????print('評分人數(shù): %s' % people)
????????print('累計票房: %s' % ticket_number1,ticket_number[1])
if __name__ =='__main__':
????maoyan = MaoYan()
????maoyan.start_crawl()
成功結(jié)束