猫眼电影@font-face设置自定义字体反爬

首先看看css3的字体,http://www.runoob.com/css3/css3-fonts.html

正文开始:打开https://piaofang.maoyan.com/?ver=normal

很高兴,又是一个字体反爬的网站,和标题对应的来了,

将其复制,并通过base64解密后保存为ttf文件,再通过fontTools,将其打开,并保存为xml文件

import base64
from fontTools.ttLib import TTFont


a=base64.b64decode('d09.........')
with open('2.ttf','wb')as f:
     f.write(a)
font = TTFont('2.ttf')
font.saveXML('2.xml')

并用High-Logic FontCreator打开,效果如下

对应的是4,很明显,就是‘uni’+''.replace('&#x','').replace(';','')。不信?多对应几个

再来打开刚刚保存的xml

<GlyphOrder>....</GlyphOrder>内包含着所有编码信息,注意前两个是不是0-9的编码,需要去除,另外不要误以为id就是对应的值,很明显是对应不上的,这里的name对应的是字符对象<TTGlyph>的name

<glyf>... </glyf>内包含着每一个字符对象<TTGlyph>,这里是第一个和最后一个不是0-9的字符,需要祛除。 画框框的才是真正对应的数字,那怎么对应起来呢?

例如打开有用的第一个,信息如下,xy可以看做是坐标,画出线图,那是否就出现具体的字体了?

出动matplotlib

import matplotlib.pyplot as plt
import re
a='''
<TTGlyph name="uniE044" xMin="0" yMin="-12" xMax="510" yMax="719">
      <contour>
        <pt x="410" y="534" on="1"/>
        <pt x="398" y="586" on="0"/>
        <pt x="377" y="609" on="1"/>
        <pt x="341" y="646" on="0"/>
        <pt x="289" y="646" on="1"/>
        <pt x="247" y="646" on="0"/>
        <pt x="215" y="623" on="1"/>
        <pt x="173" y="592" on="0"/>
        <pt x="150" y="535" on="1"/>
        <pt x="138" y="506" on="0"/>
        <pt x="125" y="423" on="0"/>
        <pt x="125" y="369" on="1"/>
        <pt x="157" y="418" on="0"/>
        <pt x="248" y="464" on="0"/>
        <pt x="299" y="464" on="1"/>
        <pt x="386" y="464" on="0"/>
        <pt x="510" y="334" on="0"/>
        <pt x="510" y="232" on="1"/>
        <pt x="510" y="165" on="0"/>
        <pt x="452" y="49" on="0"/>
        <pt x="352" y="-12" on="0"/>
        <pt x="286" y="-12" on="1"/>
        <pt x="176" y="-12" on="0"/>
        <pt x="38" y="147" on="0"/>
        <pt x="38" y="335" on="1"/>
        <pt x="38" y="543" on="0"/>
        <pt x="114" y="637" on="1"/>
        <pt x="181" y="719" on="0"/>
        <pt x="294" y="719" on="1"/>
        <pt x="379" y="719" on="0"/>
        <pt x="433" y="671" on="1"/>
        <pt x="486" y="625" on="0"/>
        <pt x="498" y="541" on="1"/>
      </contour>
      <contour>
        <pt x="139" y="232" on="1"/>
        <pt x="139" y="188" on="0"/>
        <pt x="178" y="103" on="0"/>
        <pt x="247" y="60" on="0"/>
        <pt x="285" y="60" on="1"/>
        <pt x="339" y="60" on="0"/>
        <pt x="420" y="150" on="0"/>
        <pt x="420" y="227" on="1"/>
        <pt x="420" y="300" on="0"/>
        <pt x="341" y="387" on="0"/>
        <pt x="223" y="387" on="0"/>
        <pt x="139" y="301" on="0"/>
      </contour>
      <instructions/>
    </TTGlyph>
'''
x=[int(i)for i in re.findall('x="([-]{0,1}\d+)" y="',a)]
y=[ int(i) for i in re.findall('y="([-]{0,1}\d+)" on="',a)]
plt.plot(x, y)
plt.show()

额。。。这个是6,不是8,8如下图

很高心,将uni编码与具体的数字对应起来不需要看ttf文件了

特别提示:每次访问网页的ttf文件里内容是不一样的,数字顺序不一样,uni编码也不一样。那不是需要每次画出图,通过机器视觉识别(高大上,不会的东西),答案是不需要,虽然uni与数字顺序不一样,都是每个数字对于的xy坐标是不变的,哈哈,意思就是我们将一组对应起来,之后再根据这组数据与每次访问得到的新数据的TTGlyph对象做对比即可

再对比两个6对应的TTGlyph对象

结论:一模一样,好到这就分析完了,开始代码

import requests
import re
import base64
from fontTools.ttLib import TTFont
from bs4 import BeautifulSoup


def analysis(movie_price:list,maps:list,font):
    data=[]
    for i in movie_price:
        analysis_befores=i
        analysis_before_Datas=re.findall('[a-tw-z0-9]{4}',i)
        # 获取所有<TTGlyph>的name,去除首尾
        for analysis_before_Data in analysis_before_Datas:
            analysis_before='uni'+analysis_before_Data.upper()
            obj2 = font['glyf'][analysis_before]#获取对应坐标对象
            if obj2 in maps[0] :  # 坐标是一样的,那么对应的字体也是一样的
                index=maps[0].index(obj2)
                print('\\u' + analysis_before_Data, str(maps[1][index]))
                analysis_befores=analysis_befores.replace('\\u' + analysis_before_Data, str(maps[1][index]))
        data.append(analysis_befores)
    return data
def down_ttf_xml(ttf_Data:str):
    data=base64.b64decode(ttf_Data)
    with open('new_request.ttf','wb')as f:
        f.write(data)
    font = TTFont('new_request.ttf')
    font.saveXML('new_request.xml')
    font.close()
def get_page(url:str,maps:list):
    data=[]
    headers = {
        "User-Agent": "Mozilla/5.0....",
    }
    response=requests.get(url,headers=headers,verify=False)
    ttf_Data=re.findall('charset=utf-8;base64,(.*?)\)',response.text)[0]
    down_ttf_xml(ttf_Data)
    soup = BeautifulSoup(response.text, "html.parser")
    movie_name=[]
    name_tags=soup.select('#ticket_content   div.content > ul > li.c1 > b')
    for name_tag in name_tags:
        movie_name.append(name_tag.string)
    movie_time=[]
    time_tags=soup.select('#ticket_content   div.content > ul > li.c1 > em:nth-of-type(1)')
    for time_tag in time_tags:
        movie_time.append(time_tag.string)
    movie_price=[]
    price_tags=soup.select('#ticket_content   div.content > ul > li.c1 > em:nth-of-type(2) > i')
    for price_tag in price_tags:
        # 防止自动转义
        movie_price.append(repr(price_tag.string))
    font = TTFont('new_request.ttf')
    movie_price=analysis(movie_price,maps,font)
    for i in range(len(movie_name)):
        data_1=[]
        data_1.append(movie_name[i])
        data_1.append(movie_time[i])
        data_1.append(movie_price[i])
        data.append(data_1)
    return data

if __name__=='__main__':
    url='https://piaofang.maoyan.com/?ver=normal'
    data_source = {'uniE113': 3, 'uniE3AD': 4, 'uniF55D':5, 'uniED36': 2, 'uniF57A': 8,
 'uniF7E0': 0, 'uniEB7B': 1,'uniF0ED': 9, 'uniE044': 6, 'uniF8C5': 7}
    maps=[[],[]]  #建立映射
    font = TTFont('2.ttf')
    # 获取所有<TTGlyph>的name,去除首尾
    uni_list1 = font.getGlyphNames()[1:-1]
    for uni1 in uni_list1:
        # 获取编码uni1在1.ttf中对应的对象,暂时可以理解为那一大堆坐标
        obj1 = font['glyf'][uni1]
        maps[0].append(obj1)
        maps[1].append(data_source[uni1])
    data=get_page(url,maps)
    for i in data:
        print(i)

'''
['惊奇队长', '上映3天', "'4.90亿'"]
['夏目友人帐', '上映4天', "'7091.2万'"]
['绿皮书', '上映10天', "'2.71亿'"]
['驯龙高手3', '上映10天', "'3.05亿'"]
['阿丽塔:战斗天使', '上映17天', "'8.47亿'"]
['流浪地球', '上映34天', "'45.97亿'"]
['熊出没·原始时代', '上映34天', "'7.09亿'"]
['飞驰人生', '上映34天', "'17.12亿'"]
['醒来之爱的呼唤', '上映3天', "'116.9万'"]
['魔神Z', '上映3天', "'27.5万'"]
['江海渔童之巨龟奇缘', '点映', "'23.6万'"]
['新喜剧之王', '上映34天', "'6.23亿'"]
['老师·好', '点映', "'1.7万'"]
['浴血广昌', '上映222天', "'9722.5万'"]
['朝花夕誓-于离别之朝束起约定之花', '上映17天', "'1712.9万'"]
['比悲伤更悲伤的故事', '点映', "'72.0万'"]
['一吻定情', '上映25天', "'1.73亿'"]
['古井凶灵', '上映17天', "'478.7万'"]
['逆罪', '上映10天', "'18.5万'"]
['我们的爱情', '上映3天', "'8.1万'"]
'''

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值