反爬虫之猫眼电影字体加密

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/ITcainiaoyizhan/article/details/85868113

猫眼电影里面很多数字是加密的如下图;
在这里插入图片描述
我们可以找到他们用的加密字体如下图;
两个黑线之间的字符串。
在这里插入图片描述
手工粘贴出来一份,太长中间省略了;

font_str1='d09GRgABAAAAAAggAAs.......................JnoBGUMXjA=='
# 因为网页里找到的字体字符串时经过base64加密的,用下边方法解析并且保存下载字体备用
def make_font_file(base64_string:str):
    bin_data=base64.decodebytes(base64_string.encode())
     with open('testotf2.woff','wb')as f:
         f.write(bin_data)
    return bin_data
font1=TTFont(BytesIO(make_font_file(font_str1)))
c=font1.getBestCmap()
print('40行===',c)

将下载下来的字体用FontCreatorSetup-x64软件打开,可以看到加密字体的对应关系,如下图;
在这里插入图片描述
一会需要手写一份这样的对应关系作为基础字体。因为每次刷新加密字体对应关系都会被打乱,所以需要一个基础字体进行比对。

for i in range(1,12):
        matchGlyph=match_font['glyf'][uniList[i]]
        for j in range(11):
            baseGlyph=baseFont['glyf'][baseUniCode[j]]
            if matchGlyph==baseGlyph:
                numDic[uniList[i]]=baseNumList[j]

这里比较的时每个数字的图形画法,然后重新确定当前页面的对应关系
在这里插入图片描述
完整的具体代码如下;

import base64
import re
from io import BytesIO
from PIL import Image, ImageDraw, ImageFont
import requests
from fontTools.ttLib import TTFont
from lxml import etree

url = 'http://piaofang.maoyan.com/?ver=normal'
headers = {
	'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36',
}
r = requests.get(url=url, headers=headers)
tree = etree.HTML(r.text)
classname = tree.xpath('//*[@id="ticket_tbody"]/ul[1]/li[2]/b/i/text()')[0]
font_strss=tree.xpath('//*[@id="js-nuwa"]/text()')[0]
#正则出被加密过的字体字符串
reg=re.compile('base64,(.*?)\) format\(')
s=reg.findall(font_strss)[0]
print('21行===',s)
# 因为网页每次刷新字体都会变化,所以每次都要动态获取当前的字体。
font_str2=s
#手工粘贴出来一个字体,或者下载一个字体作为基础对应字体。为后边查找对应值做参照。
font_str1='d09GRgABAAAAAAggAAsAAAA.............................GUMXjA=='
# 因为网页里找到的字体字符串时经过base64加密的,用下边方法解析
def make_font_file(base64_string:str):
    bin_data=base64.decodebytes(base64_string.encode())
    # with open('testotf2.woff','wb')as f:
    #     f.write(bin_data)
    return bin_data
font1=TTFont(BytesIO(make_font_file(font_str1)))
c=font1.getBestCmap()
print('40行===',c)

#对基础字体进行解析
baseFont=TTFont(BytesIO(make_font_file(font_str1)))
def decode_font_advance(font_strs):
    match_font=TTFont(BytesIO(make_font_file(font_strs)))
    #定义一个空字典numDic用来放当前真实的字体对应关系
    numDic={}
    #
    uniList=match_font['cmap'].tables[0].ttFont.getGlyphOrder()
    #手写的一个基础字体对应关系
    baseNumList=['.','9','0','2','8','3','1','5','6','4','7']
    baseUniCode=['x','uniE0B8','uniE141','uniF2BD','uniF620','uniF34B','uniED9A','uniED1A','uniE246','uniF52C','uniF25E']
    for i in range(1,12):
        matchGlyph=match_font['glyf'][uniList[i]]
        for j in range(11):
            baseGlyph=baseFont['glyf'][baseUniCode[j]]
            if matchGlyph==baseGlyph:
                numDic[uniList[i]]=baseNumList[j]
    nums = ''
    for i in classname:
        if i=='.':
            num='.'
        else:
            str = i.encode("unicode-escape").decode()
            k = str.split('\\u')[-1]
            num = numDic['uni'+k.upper()]
        nums+=num
    return nums
#找出当前的对应关系
nnn=decode_font_advance(font_str2)
print('71行===',nnn)
展开阅读全文

没有更多推荐了,返回首页