Python爬虫实战案例——第三例

news2024/11/25 23:41:25

文章中所有内容仅供学习交流使用,不用于其他任何目的!严禁将文中内容用于任何商业与非法用途,由此产生的一切后果与作者无关。若有侵权,请联系删除。

起点中文网月票榜加密字体处理

字体加密的原理:就是将一种特定的字体库来代替浏览器本身的字体库显示的过程。

基本流程:

  1. 请求页面
  2. 获取加密的字体库
  3. 解析字体库,获取字体间的映射关系
  4. 获取加密的字体,获取字体间的映射关系,一一对应

地址:aHR0cHM6Ly93d3cucWlkaWFuLmNvbS9yYW5rL3l1ZXBpYW8v

在这里插入图片描述

请求模板:

class SendRequest:
    def __init__(self):
        self.url = 'aHR0cHM6Ly93d3cucWlkaWFuLmNvbS9yYW5rL3l1ZXBpYW8v'
        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, headers=self.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后面的内容转换成十进制观察。

在这里插入图片描述

现在我们来将这些数字简单的和网页中看到的数字对比一下看看是否得出正确的映射关系。如第一部小说的月票数据内容

𘞟𘞡𘞜𘞛𘞛𘞜

从页面中看到的月票量为105665,那么就是说100255映射的值为1,100257映射的值为0,我们来验证一下是否如此呢。从XML中找到1相关的映射

<map code="0x1879f" name="one"/><!-- ???? -->

在这里插入图片描述

刚好,那继续验证一下后面的数字呢,如0

<map code="0x187a1" name="zero"/><!-- ???? -->

在这里插入图片描述

也对应上了,后续继续验证也是对应的,所以就是说我们能够从xml文件中的cmap标签中获取到对应的映射关系,然后将html源码中的加密内容与其进行映射就可以获取到明文内容了。

完整代码如下:

import requests
import re
from lxml import etree
from fontTools.ttLib import TTFont


class 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, headers=self.headers)
        return response


class QiDian(SendRequest):
    def getIndex(self):
        response = self.URequest()
        text_html = response.content.decode()
        with open('qidian.html', 'w', encoding='utf-8')as f:
            f.write(text_html)
        woff_url = re.findall("format\('eot'\); src: url\('(.*?)'\) format\('woff'\)", text_html)[0]
        self.url = woff_url
        novel_titles = etree.HTML(text_html).xpath('//*[@id="book-img-text"]/ul/li/div[2]/h2/a/text()')
        print(novel_titles)
        tickets = re.findall('</style><span 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_map

    def 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_ticket
        print(result)


if __name__ == '__main__':
    q = QiDian()
    q.dealFont()

执行结果:

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/941172.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

8.28 菱形继承 虚继承 多态 模板

#include <iostream>using namespace std;class Animal { public:Animal() {cout << "111" <<endl;}virtual void perform() 0; };class Dol:public Animal { public:Dol() {}void perform(){cout << "海豚" << endl;} };c…

人须在事上磨 方才立得住|「云上百世慧」锐评

巨大的用户群体绝不仅意味着金山银山&#xff0c;还意味着责任如山。——《人民日报》 云上百世慧&#xff0c;智能制造专题研讨会顺利开展&#xff0c;吸引了行业内的不少人才前来参会。 云上百世慧举办三期&#xff0c;共吸引行业人员400余名&#xff0c;参会企业90余家。 …

无涯教程-Python机器学习 - Stochastic Gradient Boosting函数

它也称为梯度提升机。在下面的Python食谱中,我们将通过使用pima Indians糖尿病数据集上的 sklearn 的 GradientBoostingClassifier 类来创建随机梯度Boostingensemble模型进行分类。 首先,导入所需的软件包,如下所示: from pandas import read_csv from sklearn.model_select…

从零开始探索C语言(二)----变量、常量和存储类

文章目录 1. C 变量1.1 C 中的变量定义1.2 变量初始化1.3 变量不初始化1.4 C 中的变量声明1.5 C 中的左值和右值 2. C 常量2.1 整数常量2.2 浮点常量2.3 字符常量2.4 字符串常量2.5 定义常量2.6 #define 与 const 区别 3. C 存储类3.1 auto 存储类3.2 register 存储类3.3 stati…

checkstyle检查Java编码样式:javadoc注释检查

说明 checkstyle可以检查javadoc注释是否符合规范。 Javadoc注释以/**开头&#xff0c;以 */结尾&#xff0c;可以被javadoc等工具提取&#xff0c;形式如&#xff1a; /*** 保存了一些常数.* author thb**/Javadoc注释的首行以句号&#xff08;.&#xff09;、问号&#xf…

博客写长篇,公众号写短篇

博客使用的markdown格式非常适合技术类的文章&#xff0c;我大部分博客的内容写的都很长&#xff0c;有一部分很深的内容&#xff0c;也有特别基础的内容。 因为之前写博客总会花费太多时间&#xff0c;所以量比较少&#xff0c;现在打算用更少的时间在公众号写一些简单的内容…

富文本base64字符串转file文件上传

1.富文本以html字符串格式存储 2.以图片为例&#xff0c;获取img base64字符串,转为file文件 let content "" const regEx /(?<(img src"))[^"]*?(?")/gims; let imgs content.match(regEx); let fileList []; for (let i …

8.28day48

198. 打家劫舍 - 力扣&#xff08;LeetCode&#xff09; 知识点&#xff1a;动规五部 1.dp数组的含义&#xff1a;dp数组表示打劫改房间的最大收益 2.递推公式&#xff1a;打劫i家&#xff1a;从后往前推 我们如果打劫第i家 那么第i-1家绝对不可能背打劫 所以&#xff1a;dp…

跟这几个全日制专业相比,MBA/MEM/MPA的难度只能算小弟弟~

每年很多在职考生会因为MBA联考的难度而选择放弃&#xff0c;但实际上管理类硕士的初试难度目前来说应该是国内所有双证硕士考试中最容易的类别之一了。就从每年几个在职类专业的国家线也看得出来总体竞争并未达到十分惨的地步&#xff1a; 客观来说&#xff0c;300分总分…

免费高清图片素材库,我推荐这6个~赶紧收藏!

找高清图片素材就上这6个网站&#xff0c;我强推。免费、付费、商用的素材都能找到&#xff0c;赶紧先收藏起来吧&#xff01; 菜鸟图库 美女图片|手机壁纸|风景图片大全|高清图片素材下载网 - 菜鸟图库 网站主要为新手设计师提供免费素材&#xff0c;这些素材的质量都很高&a…

【JS真好玩】自动打字机效果

目录 一、前言二、布局分析三、总体样式四、中间部分五、底部5.1 div5.2 label5.3 input 六、JS让它动起来6.1定时器6.2 字符串处理6.2.1 slice6.2.2 splice6.3.3 split 七、总结 一、前言 大家好&#xff0c;今天实现一个自动打字机效果&#xff0c;旨在实现一些网上很小的de…

【C++题解】[广州大学附属中学-AKCSP2022信心联考]数组树

P a r t Part Part 1 1 1 读题 题目描述 w g y wgy wgy有 n n n个很不错的数&#xff0c;第 i i i个数是 a i a_i ai​&#xff0c;他想用它们组一棵数树送给 a y b ayb ayb。 a y b ayb ayb对一棵数树的喜爱程度是这棵数树的每个子树包含的数的和的总和。简单来说&#xff0…

【数据结构与算法系列1】 二分法查找

给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一个目标值 target &#xff0c;写一个函数搜索 nums 中的 target&#xff0c;如果目标值存在返回下标&#xff0c;否则返回 -1。 示例 1: 输入: nums [-1,0,3,5,9,12], target 9 输出: 4 解释: 9 出现…

软件与软件工程

软件 软件的概念以及特点&#xff1a; 软件是计算机系统中不可或缺的一部分&#xff0c;与硬件共同构成特定的系统功能。 人们通常把各种不同功能的程序&#xff0c;包括系统程序、应用程序、用户自己编写的程序等称为软件 软件的概念: 软件不仅包括程序&#xff0c;还包括程序…

Linux环境下的内存管理(2/7)

要想深入理解内存中的堆栈管理机制&#xff0c;孤立地分析并不是一个好方法&#xff0c;因为堆栈内存不是仅靠程序本身来维护的&#xff0c;而是由操作系统、编译器、CPU、物理内存相互配合实现的。 在 Linux 环境下运行的程序&#xff0c;在编译时链接的起始地址都是相同的&a…

vue左侧漏斗切换 echart图表动态更新

这个需求是根据点击左侧的箭头部分&#xff0c;右侧图表切换&#xff0c;左侧选中数据高亮&#xff08;图片用的svg&#xff09; 一、效果图 二、vue组件 <template><div class"funnel_wrap"><div class"flex_between"><div class&q…

家政服务小程序制作教程:从设计到开发的详细步骤

在当今的数字化时代&#xff0c;小程序已经成为了一种趋势&#xff0c;不仅提供了方便快捷的应用体验&#xff0c;也成为了各种行业进行营销和客户管理的有力工具。特别是对于家政行业&#xff0c;通过小程序的应用&#xff0c;可以更好地进行业务管理&#xff0c;提升服务质量…

自动化PLC工程师能否转到c#上位机开发?

成功从自动化PLC工程师转向C#上位机开发的经历可能因人而异&#xff0c;以下是一些分享的思路和建议&#xff1a;扩展编程技能&#xff1a;学习C#语言和相关的开发工具和框架&#xff0c;掌握语言的基础知识和常用的编程技巧。可以通过在线教程、培训课程、书籍等途径进行学习&…

深度学习-4-二维目标检测-YOLOv3理论模型

单阶段目标检测模型YOLOv3 R-CNN系列算法需要先产生候选区域&#xff0c;再对候选区域做分类和位置坐标的预测&#xff0c;这类算法被称为两阶段目标检测算法。近几年&#xff0c;很多研究人员相继提出一系列单阶段的检测算法&#xff0c;只需要一个网络即可同时产生候选区域并…

基于数据湖的多流拼接方案-HUDI实操篇

目录 一、前情提要 二、代码Demo &#xff08;一&#xff09;多写问题 &#xff08;二&#xff09;如果要两个流写一个表&#xff0c;这种情况怎么处理&#xff1f; &#xff08;三&#xff09;测试结果 三、后序 一、前情提要 基于数据湖对两条实时流进行拼接&#xff0…