Python高阶爬虫必备:保姆级教程带你快速破解GlidedSky字体反扒-2


前言

时隔这么多天,终于能有时间写抽空写篇博文了,正值今天1024程序员节,所以写了篇字体反扒博文给大家,希望大家看后能有所搜获!

本次反扒对象是 GlidedSky 网站的题目,说实话有点难度,但逻辑搞通的话其实还好,话不多说,开搞!!!

温馨提示:如果想练习需要先注册账号,而且题目不是一次性全部出来的,类似于闯关类型,如果是新用户需要先完成前面的题,才能解锁后面的题目,对于前面题目的讲解,我已经发表过博文了,想看的可以去看看。


1、网页查看

在我爬取之前已经有110个人完成了这次题目。
在这里插入图片描述
在这里插入图片描述
总共有1000页,多页爬取参考如下,只需更改page参数即可

在这里插入图片描述


2、反扒过程讲解(慢慢看)

打开控制台查看网页,可见网页显示的是各种表示数字的文字罗马数字或数,二网页源码中则为汉字,这其实就是经过加密后的结果,咱们接着看。
在这里插入图片描述
往上看父标签,可见引入了style
在这里插入图片描述
搜索style中的font-family
在这里插入图片描述
这就是网页内嵌的Base64存储字体加密的文件,我们在python代码中使用TTFont获取并解析这段文件如下

在这里插入图片描述

在这里插入图片描述
进过博主实测后,我们需获取网页源码汉字并转为ACSII码获取对应cmap中map的code值,再将code值转为unicode编码(python获取时默认做了),去GlyphID获取对应的id值,id值-1即为真实数字


3、反扒完整代码

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

#头信息
headers = {
    
    
    "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36",
    #记得填上cookie,参考图1
    "Cookie": ""
}
#最后保存总和的变量
sum = 0


#爬取
def download(response):
	#引入全局变量sum
    global sum
    html_data = response.text
    with open("字体文件2.html", mode="w") as f:
        f.write(html_data)

	#使用re模块正则匹配到当前网页中的base64字体文件,参考图2
    font_base = re.findall("base64,(.*?)\) format", response.text)[0]
    #使用base64库进行解码
    result = base64.b64decode(font_base)
    with open("字体文件2.ttf", mode="wb") as f:
        f.write(result)

	#使用TTFont打开字体文件并保存为xml文件以供阅读
    font = TTFont('字体文件2.ttf')
    font.saveXML("font2.xml")
    # 获取字体映射关系,参考图2
    font_map = font.getGlyphOrder()
    font_cmap = font['cmap'].getBestCmap()
    #将font-cmap中的key、value值对换位置
    #zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
    font_cmap = dict(zip(font_cmap.values(), font_cmap.keys()))

    lists = []
    font_map_new = []
    for name in font_map:
        if name == '.notdef':
        	continue
    	#根据name值获取对应的id值并添加到lists中,参考图2
    	#将获取到的数减一,再添加到lists列表中去,id值-1即为最终真实的数字
        lists.append(font.getGlyphID(name) - 1)
    for name in font_map:
    	#.notdef是我们不需要的,如果为.notdef直接使用continue进入下次循环
        if name == '.notdef':
            continue
        font_map_new.append(name)
    #GlyphOrder映射
    dicts = dict(zip(font_map_new, lists))
    
    # 更改映射
    t1 = []
    t2 = []
    for key in dicts.keys():
    	#chr()主要用来表示ascii码对应的字符他的输入时数值
    	#t1保存font_cmap中对应key值即acsii码对应的数值
        t1.append(chr(font_cmap[key]))
        #t2保存dicts中key对应的value值
        t2.append(dicts[key])
	#最终映射结果,参考图3
    t3 = dict(zip(t1,t2))


    #数据爬取处理流程,参考图4
    data = BeautifulSoup(html_data, "lxml")
    numbers = data.find(class_="row").find_all(class_="col-md-1")
    for num in numbers:
        num = BeautifulSoup(str(num), "lxml")
        num_temp = num.text.strip()
        l = list(str(num_temp))
        #遍历l,然后获取对应t3中的值并保存
        for i in range(len(l)):
            l[i] = str(t3.get(l[i]))
        #拼接l中的值然后进行累加
        sum = sum + int("".join(l))


#开始
if __name__ == '__main__':
	#多页爬取
    for i in range(1000):
        print("正在爬取第"+str(i+1)+"页")
        #拼接page值
        url = "http://glidedsky.com/level/web/crawler-font-puzzle-2?page=" + str(i)
        #发起请求
        response = requests.get(url=url, headers=headers)
        #设置编码
        response.encoding = 'utf-8'
        download(response)
    #执行完后打印总和
    print(sum)

4、图片辅助分析

图1
在这里插入图片描述

图2
在这里插入图片描述
图3

图4
在这里插入图片描述


5、运行结果

在这里插入图片描述

在这里插入图片描述
成功!!!


博主会持续更新,有兴趣的小伙伴可以点赞关注收藏下哦,你们的支持就是我创作最大的动力!

几十个宝藏爬虫项目教程,你值得拥有!

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/llllllkkkkkooooo/article/details/109264902
今日推荐