【Python网络蜘蛛 · 11】:qi+dian 字体fan + pa分析

本文介绍了一位前端开发者如何通过分析网页和woff文件,解密小说网站上加密的月票数据,揭示了从加密字符到实际数值的转换过程。通过字体文件和编码映射,成功获取了每部小说的月票数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1、目标 

2、网页分析

 二、思路步骤

1、找到关系映射表 

搜索cmap找到map标签 

 2、提供思路:解密一个数

3、编写代码思路

获取woff文件url、加密关键数据、加密的月票数据、小说名

获取关系映射表,解密数据 


1、目标 

  • 我们要获取的内容就是每部小说的月票数

2、网页分析

  • 我们通过网页检查,定位月票数时发现月票的数据被加密了

  •  于是我们通过抓包,找到月票所在的数据包,发现在数据包的响应内容中,月票数被一些奇奇怪怪的数字和字符代替:
  • 𘢓𘢓𘢓𘢏𘢒

  •  这些字符就是被加密后的样子,这时我们需要去找到解密的方法,我们可以在数据包中的响应内查看多个被加密的月票数据,发现他们都会有相同之处,那就是有一个相同的属性值:GzXdLunT,并且在font-face中出现了一个GzXdLunT.woff文件,所以这个属性值就是我们破案的关键。

  • 于是我们复制该属性值,在出现的各种数据包中查找是否有包含该属性值的文件名,于是我们找到了一个文件:GzXdLunT.woff

  •  当我们鼠标双击该文件时,文件会自动下载

 将此文件拖到我们的python文件目录中

 


 二、思路步骤

1、找到关系映射表 

基本步骤:

  • 利用python方法将woff文件转换成xml格式 -- 搜索cmap -- 找到map标签 -- 找到月票数据的对应关系

woff文件转换成xml文件的方法:利用 fontTools 模块

  • 导入模块from fontTools.ttLib import TTFont
  • 创建对象,参数为字体加密文件:font = TTFont('GzXdLunT.woff')
  • 转换成xml格式:font.saveXML('f.xml')

 代码演示

# 利用python中的方法进行转换
# 1.fontTools模块
# 2.转换成xml格式 -- 搜索cmap -- 找到map标签 -- 找到对应关系

from fontTools.ttLib import TTFont
# 创建对象,参数为字体加密文件
font = TTFont('GzXdLunT.woff')

#转换成html文件
font.saveXML('f.xml')
  •  运行结果,生成了一个f.xml文件

  • 搜索cmap找到map标签 

在map标签中我们可以看到code的属性值是一个16进制数,而且每个code后都有一个name属性,其值就是英文数字,而这个十六进制数转换成十进制就变成了月票中加密的数据,对应的name值就是月票数。

 2、提供思路:解密一个数

我们解密月票的一个数字7,它加密的变成的是:&#100499 

 在关系映射表中找到,name的属性值为seven的map标签,复制map标签中的code属性值,将其转换成十进制

 

 数据对应上了

3、编写代码思路

注意:woff文件是不断更新的,所以需要先获取到最新的woff文件   

获取woff文件url、加密关键数据、加密的月票数据、小说名

  • 首先构建一个字典,获取向网页发送请求
li = []
url = 'https://www.qidian.com/rank/yuepiao/'
headers = {
    'User-Agent': ',
    'Cookie': '',
    'Referer': ''
}
res = requests.get(url, headers=headers)
  • 先获取月票数据对应加密的文件,(正则获取)

#获取月票数据对应加密的文件
li_url = re.findall("\); src: url\('(.*?)'\) format\('woff'\),",res.text)[0]
  •  获取加密的关键字(正则获取)

#获取加密的关键字
li_key = re.findall("https://qidian.gtimg.com/qd_anti_spider/(.*?).woff",li_url)[0]
  •  获取加密的月票数据(正则获取)

 

#获取加密的月票数据
li_data = re.findall(f'<span class="{li_key}">(.*?)</span></span>月票</p>',res.text)
  •  获取小说名
#获取小说名
html = etree.HTML(res.text)
li_name = html.xpath('//*[@id="book-img-text"]/ul/li[*]/div[2]/h2/a/text()')
  • 将加密文件url、加密的月票数据放入、小说名放到列表li中
li = []
li.append(li_url) #放入加密文件url
li.append(li_data) #放入加密数据
li.append(li_name) #放入小说名
  • 列表li中的数据展示 

​ 

获取关系映射表,解密数据 

  • 对加密文件url发送请求 
url = li[0]
headers = {
        'User-Agent': ''
    }
res1 = requests.get(url, headers=headers)
  •  保存xml文件
font2 = TTFont(BytesIO(res1.content)) #BytesIO在内存中读写bytes
font2.saveXML('c.xml')
  •  获取关系映射表
cmap = font2.getBestCmap()
  •  构建一个字典,用来翻译
trans = {'zero':0,'one':1, 'two':2, 'three':3, 'four':4, 'five':5, 'six': 6, 'seven':7, 'eight':8, 'nine':9}
  •  通过for循环,清洗加密的月票数据,也就是将&#100499清洗成100499
    n = 0
    li_num = []
    for i in li[1]:
        n += 1
        data = f'月票榜第{n}:'
        #定义以一个空列表,用来存放匹配出的英文排序
        li1 = []
        cp1 = re.findall('.#(.*?);', i) #通过正则,分离出想要的信息
        for j in cp1:
            li1.append(cmap[int(j)])
        #读出月票数
        for k in li1:
            data += str(trans[k])
        li_num.append(data)
  • 将小说名和月票数保存在csv文件中
f = open('小说.csv', 'a', encoding='utf-8')
#基于文件对象构建csv写入对象
csv_write = csv.writer(f)
#构建表头
csv_write.writerow(["小说", "月票"])
for i in range(len(li_num)):
#写入csv文件内容
csv_write.writerow([f"{li[2][i]}", f"{li_num[i]}"])

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

街 三 仔

你的鼓励是我创作的最大动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值