网站的访问量,中国十大公司排名,黄石做网站的,工程交易信息网文章中所有内容仅供学习交流使用#xff0c;不用于其他任何目的#xff01;严禁将文中内容用于任何商业与非法用途#xff0c;由此产生的一切后果与作者无关。若有侵权#xff0c;请联系删除。
起点中文网月票榜加密字体处理
字体加密的原理#xff1a;就是将一种特定的…文章中所有内容仅供学习交流使用不用于其他任何目的严禁将文中内容用于任何商业与非法用途由此产生的一切后果与作者无关。若有侵权请联系删除。
起点中文网月票榜加密字体处理
字体加密的原理就是将一种特定的字体库来代替浏览器本身的字体库显示的过程。
基本流程
请求页面获取加密的字体库解析字体库获取字体间的映射关系获取加密的字体获取字体间的映射关系一一对应
地址aHR0cHM6Ly93d3cucWlkaWFuLmNvbS9yYW5rL3l1ZXBpYW8v 请求模板
class SendRequest:def __init__(self):self.url aHR0cHM6Ly93d3cucWlkaWFuLmNvbS9yYW5rL3l1ZXBpYW8vself.headers {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36,referer: }self.session requests.session()def URequest(self):response self.session.get(self.url, headersself.headers)return response首先是对该页面进行抓包分析 可以看到目标数据是在HTML页面中的静态数据但是月票数据却是加密内容其源码中内容如下 所以接下来我们需要做的就是将这段加密的内容还原成准确的文字这里由于适合字体显示有关所以我们可以先看一下这部分标签对于字体的相关设置 刚好就说在这个标签上可以看到对于这些字体的配置同时我们可以看到span标签的字体是由woff文件渲染的所以我们可以先将这个字体文件下载到本地然后找一下是否有关于字体相关的映射关系。下载完成后在Python中通过fonttools模块(pip install fonttools)来对字体文件进行初步处理。
from fontTools.ttLib import TTFont# 使用TTfont打开一个本地存在的字体文件
font_file TTFont(BRoBcAgB.woff)
# 转换成XML文档
font_file.saveXML(BRoBcAgB.xml)通过fonttools保存为xml文件之后从里面可以看到相关的映射关系。 然后我们可以将code后面的内容转换成十进制观察。 现在我们来将这些数字简单的和网页中看到的数字对比一下看看是否得出正确的映射关系。如第一部小说的月票数据内容
#100255;#100257;#100252;#100251;#100251;#100252;从页面中看到的月票量为105665那么就是说100255映射的值为1,100257映射的值为0,我们来验证一下是否如此呢。从XML中找到1相关的映射
map code0x1879f nameone/!-- ???? --刚好那继续验证一下后面的数字呢如0
map code0x187a1 namezero/!-- ???? --也对应上了后续继续验证也是对应的所以就是说我们能够从xml文件中的cmap标签中获取到对应的映射关系然后将html源码中的加密内容与其进行映射就可以获取到明文内容了。
完整代码如下
import requests
import re
from lxml import etree
from fontTools.ttLib import TTFontclass SendRequest:def __init__(self):self.url https://www.qidian.com/rank/yuepiao/self.headers {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36,referer: }self.session requests.session()def URequest(self):response self.session.get(self.url, headersself.headers)return responseclass QiDian(SendRequest):def getIndex(self):response self.URequest()text_html response.content.decode()with open(qidian.html, w, encodingutf-8)as f:f.write(text_html)woff_url re.findall(format\(eot\); src: url\((.*?)\) format\(woff\), text_html)[0]self.url woff_urlnovel_titles etree.HTML(text_html).xpath(//*[idbook-img-text]/ul/li/div[2]/h2/a/text())print(novel_titles)tickets re.findall(/stylespan class\w(.*?);/span/span月票/p, text_html)print(tickets)woff_res self.URequest()with open(qidian.woff, wb)as f:f.write(woff_res.content)font_file TTFont(qidian.woff)font_file.saveXML(qidian.xml)best_map font_file.getBestCmap()return novel_titles, tickets, best_mapdef dealFont(self):novel_titles, tickets, best_map self.getIndex()zh_en {zero: 0, one: 1, two: 2, three: 3,four: 4, five: 5, six: 6, seven: 7,eight: 8, nine: 9}result {} # 用于存放最终的数据键为书名值为月票for i, j in zip(novel_titles, tickets):t_num j.replace(#, ).split(;) # 消除#后以分号进行分割print(t_num)res_ticket # 用于记录每一本书字体解密之后的内容for l in t_num:res_ticket str(zh_en[best_map[int(l)]]) # 根据网站中提取出来的加密数据映射字体文件中# 的目标值然后由于目标值是英文所以需要映射成阿拉伯数字最后进行连接称为该本书最终的月票信息result[i] res_ticketprint(result)if __name__ __main__:q QiDian()q.dealFont()执行结果