Glidedsky系列—字体反爬

前言题目地址:http://glidedsky.com/level/web/crawler-font-puzzle-1提示:以下是本篇文章正文内容,下面案例可供参考一、题目描述二、题目分析1.网页分析我们可以看到div的文本内容,跟网页显示是不一样的,这次题目是通过加载对应的字体文件,把文本内容映射成最后我们看到网页显示的结果,我们在网页源码中可以看到base64加密后的字体文件,通过正则获取其内容再通过base64解密我们就可以获得对应的二进制字体文件2.读入数据代码如下(示例)
摘要由CSDN通过智能技术生成

前言

题目地址:http://glidedsky.com/level/web/crawler-font-puzzle-1


提示:以下是本篇文章正文内容,下面案例可供参考

一、题目描述

在这里插入图片描述

二、题目分析

1.网页分析

在这里插入图片描述

我们可以看到div的文本内容,跟网页显示是不一样的,这次题目是通过加载对应的字体文件,把文本内容映射成最后我们看到网页显示的结果,我们在网页源码中可以看到base64加密后的字体文件,通过正则获取其内容再通过base64解密我们就可以获得对应的二进制字体文件
在这里插入图片描述
在这里插入图片描述
获取到字体文件后,我们可以通过fontTools库把字体文件转化成我们看得懂的xml文件
在这里插入图片描述
我们通过寻找规律发现id-1对应的name值,就是它们间的映射关系,即在这个字体文件下,网页div值为2,对应的映射关系便是6(字体文件每次都会改变,但映射逻辑没变),我们只需要一个列表,存放id1-id10的值,以div的数值作为下标去取出列表的数,就是网页显示出来的结果

2.源码

import re
import time

import requests
import base64
from fontTools.ttLib import TTFont
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0'
}
login_url = "http://glidedsky.com/login"

num_dict = {
    'zero':'0','one':'1','two':'2','three':'3','four':'4','five':'5','six':'6','seven':'7','eight':'8','nine':'9'}

def get_token():
    resp = s.get(login_url)
    token = re.findall('<meta name="csrf-token" content="(.*?)">', resp.text)[0]
    return token

def page_sum(detail_url):
    page_text = s.get(url=detail_url).text
    #获取加密的字体文件
    font_url = re.findall(r'base64,(.*?)\) format',page_text)[0]
    #base64解码
    str_ttl = base64.b64decode(font_url)
    with open('zt.ttf', 'wb')as fp:
        fp.write(str_ttl)
    font= TTFont('zt.ttf')
    #保存为可以看懂的xml文件
    font.saveXML('zt.xml')
    #获取id1-id10的值
    font_map = font.getGlyphOrder()[1:]
    #把id1-id10的值转为字符串型的数字
    num_list = [num_dict[i] for i in font_map]
    #构建映射关系
    mapping_dict=dict(zip(num_list,[str(i) for i in range(10)]))
    #print(mapping_dict)

    #遍历每个div的值
    base_num = re.findall(r'<div class="col-md-1">.*?(\d+).*?</div>', page_text, re.S)
    sum1 = 0
    #遍历div值中的每个数字
    for num in base_num:
        rel_num = ''
        #根据映射关系,转换每个数字
        for i in num:
            rel_num += mapping_dict[i]
        sum1 += int(rel_num)
    return sum1

s = requests.session()

data = {
    '_token' : get_token(),
    'email' : '账号',
    'password' : "密码"
}

s.post(url = login_url,data=data)
num_sum = 0
for i in range(1,1001):
    num_sum+= page_sum('http://www.glidedsky.com/level/web/crawler-font-puzzle-1?page=%d'%i)
    print('第{}页计算完毕'.format(i))

print(num_sum)



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值