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

2023-11-15

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

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

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

基本流程:

  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()

执行结果:

在这里插入图片描述

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python爬虫实战案例——第三例 的相关文章

  • Spark 请求最大计数

    我是 Spark 的初学者 我尝试请求允许我检索最常访问的网页 我的要求如下 mostPopularWebPageDF logDF groupBy webPage agg functions count webPage alias cntW
  • 使用 python 进行串行数据记录

    Intro 我需要编写一个小程序来实时读取串行数据并将其写入文本文件 我在读取数据方面取得了一些进展 但尚未成功地将这些信息存储在新文件中 这是我的代码 from future import print function import se
  • 我怎样才能更多地了解Python的内部原理? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我使用Python编程已经有半年多了 我对Python内部更感兴趣 而不是使用Python开发应用程序
  • Python模块可以访问英语词典,包括单词的定义[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个 python 模块 它可以帮助我从英语词典中获取单词的定义 当然有enchant 这可以帮助我检查该单词是否存在于英语中
  • 如何使用 Plotly 中的直方图将所有离群值分入一个分箱?

    所以问题是 我可以在 Plotly 中绘制直方图 其中所有大于某个阈值的值都将被分组到一个箱中吗 所需的输出 但使用标准情节Histogram类我只能得到这个输出 import pandas as pd from plotly import
  • 如何使用 imaplib 获取“消息 ID”

    我尝试获取一个在操作期间不会更改的唯一 ID 我觉得UID不好 所以我认为 Message ID 是正确的 但我不知道如何获取它 我只知道 imap fetch uid XXXX 有人有解决方案吗 来自 IMAP 文档本身 IMAP4消息号
  • 将数据帧行转换为字典

    我有像下面的示例数据这样的数据帧 我正在尝试将数据帧中的一行转换为类似于下面所需输出的字典 但是当我使用 to dict 时 我得到了索引和列值 有谁知道如何将行转换为像所需输出那样的字典 任何提示都非常感激 Sample data pri
  • python suds SOAP 请求中的名称空间前缀错误

    我使用 python suds 来实现客户端 并且在发送的 SOAP 标头中得到了错误的命名空间前缀 用于定义由element ref 在 wsdl 中 wsdl 正在引用数据类型 xsd 文件 请参见下文 问题出在函数上GetRecord
  • 使用 OLS 回归预测未来值(Python、StatsModels、Pandas)

    我目前正在尝试在 Python 中实现 MLR 但不确定如何将我找到的系数应用于未来值 import pandas as pd import statsmodels formula api as sm import statsmodels
  • 如何通过在 Python 3.x 上按键来启动和中断循环

    我有这段代码 当按下 P 键时会中断循环 但除非我按下非 P 键 否则循环不会工作 def main openGame while True purchase imageGrab if a sum gt 1200 fleaButton ti
  • 对图像块进行多重处理

    我有一个函数必须循环遍历图像的各个像素并计算一些几何形状 此函数需要很长时间才能运行 在 24 兆像素图像上大约需要 5 小时 但似乎应该很容易在多个内核上并行运行 然而 我一生都找不到一个有据可查 解释充分的例子来使用 Multiproc
  • 如何设置 Celery 来调用自定义工作器初始化?

    我对 Celery 很陌生 我一直在尝试设置一个具有 2 个独立队列的项目 一个用于计算 另一个用于执行 到目前为止 一切都很好 我的问题是执行队列中的工作人员需要实例化一个具有唯一 object id 的类 每个工作人员一个 id 我想知
  • python Soap zeep模块获取结果

    我从 SOAP API 得到如下结果 client zeep Client wsdl self wsdl transport transport auth header lb E authenticate self login res cl
  • mac osx 10.8 上的初学者 python

    我正在学习编程 并且一直在使用 Ruby 和 ROR 但我觉得我更喜欢 Python 语言来学习编程 虽然我看到了 Ruby 和 Rails 的优点 但我觉得我需要一种更容易学习编程概念的语言 因此是 Python 但是 我似乎找不到适用于
  • 迭代 my_dict.keys() 并修改字典中的值是否会使迭代器失效?

    我的例子是这样的 for my key in my dict keys my dict my key mutate 上述代码的行为是否已定义 假设my dict是一本字典并且mutate是一个改变其对象的方法 我担心的是 改变字典中的值可能
  • 当鼠标悬停在上面时,intellisense vscode 不显示参数或文档

    我正在尝试将整个工作流程从 Eclipse 和 Jupyter Notebook 迁移到 VS Code 我安装了 python 扩展 它应该带有 Intellisense 但它只是部分更糟糕 我在输入句点后收到建议 但当将鼠标悬停在其上方
  • 限制 django 应用程序模型中的单个记录?

    我想使用模型来保存 django 应用程序的系统设置 因此 我想限制该模型 使其只能有一条记录 极限怎么办 尝试这个 class MyModel models Model onefield models CharField The fiel
  • Elastic Beanstalk 中的 enum34 问题

    我正在尝试在 Elastic Beanstalk 中设置 django 环境 当我尝试通过requirements txt 文件安装时 我遇到了python3 6 问题 File opt python run venv bin pip li
  • 检查字典键是否有空值

    我有以下字典 dict1 city name yass region zipcode phone address tehsil planet mars 我正在尝试创建一个基于 dict1 的新字典 但是 它不会包含带有空字符串的键 它不会包
  • 您可以使用关键字参数而不提供默认值吗?

    我习惯于在 Python 中使用这样的函数 方法定义 def my function arg1 None arg2 default do stuff here 如果我不供应arg1 or arg2 那么默认值None or default

随机推荐

  • Java选择排序

    1 选择排序 选择排序是一种简单直观的排序算法 其基本原理是每一次从待排序的数组里找到最小值 最大值 的下标 然后将最小值 最大值 跟待排序数组的第一个进行交换 然后再从剩余的未排序元素中寻找到最小 大 元素 然后放到已排序的序列的末尾 反
  • 2.Node.js的安装 及 小案例——实现Hello World

    1 编辑器 初期 记事本Ediplus Nodepad 后期 Webstrom Hbuilder 2 Node js的下载 安装 测试 1 下载 http nodejs cn 2 安装 在windows版本操作系统下 直接点击 下一步 即可
  • vue+element在el-table表头添加搜索框实现模糊查询

    页面初始展示 实现模糊查询 gt
  • 如何理解邮件中的“CC、PS、FYI”等英文缩写?

    文章目录 2015年皮卡丘大学毕业初 加入一家总部在荷兰的外企 刚入职邮件中的英文缩写把皮卡丘折磨的晕头转向 比如OOO CC FYI OMW 你知道这些缩写表达的意思吗 01 OOO 是什么意思 OOO千万别理解成 哦哦哦 OOO Out
  • 安装虚拟机VMWare后再装LINUX系统(含避坑指南)

    一 下载 到官网下载虚拟机VMware Download VMware Workstation Pro 二 安装前的电脑设置 不要着急装 不设置好是安装不了的 还会引起暴躁 1 BIOS模式开启intel vt x 一般是禁用的 即 Int
  • 基于Native.js实现Android文件的读写操作

    Native js技术 简称NJS 是一种将手机操作系统的原生对象转义 映射为JS对象 在JS里编写原生代码的技术 我们在进行APP混合开发过程中免不了需要调用Andriod底层的一些API 也免不了可能会涉及到文件读取的操作之类的功能 这
  • Devops

    最近老是碰到这个名词 所以想了解一下这个到底是撒玩意 DevOps Development和Operations的组合词 是一组过程 方法与系统的统称 用于促进开发 应用程序 软件工程 技术运营和质量保障 QA 部门之间的沟通 协作与整合
  • windows利用kubectl命令和vscode远程操作kubenetes(k8s)

    windows 中安装kubecltl 命令 下载地址 http pwittrock github io docs tasks tools install kubectl install with chocolatey on windows
  • java 判断两个list是否相等的方法

    以下示例可以当做一个反面教材 实际是错误的 public static boolean isEquals List
  • 用apache实现禁止IP段或者主机对某个目录的访问

    Allow 指令 说明 控制哪些主机能够访问服务器的一个区域 语法 Allow from all host env env variable host env env variable 上下文 目录 htaccess 覆盖项 Limit 状
  • LayUI系列(一)之layui介绍以及登录功能的实现

    文章目录 一 layui简介 1 1 layui介绍 1 2 主要构成 1 3 迭代历程 1 4 layui easyui和bootstrap对比 1 4 1 layui与bootstrap对比 这两个都属于ui渲染框架 1 4 2 lay
  • TensorFlow框架做实时人脸识别小项目(一)

    人脸识别是深度学习最有价值也是最成熟的的应用之一 在研究环境下 人脸识别已经赶上甚至超过了人工识别的精度 一般来说 一个完整的人脸识别项目会包括两大部分 人脸检测与人脸识别 下面就我近期自己练习写的一个 粗糙 的人脸识别小项目讲起 也算是做
  • 二、关系模型

    关系模型 关系模型由关系数据结构 关系操作集合和关系完整性约束三部分组成 关系数据结构 关系模型的数据结构非常简单 只包含单一的数据结构 关系 域 一组具有相同数据类型的值的集合 笛卡儿积 在域上的一种集合运算 例如A 1 2 B a b
  • NNDL 作业7:第五章课后题(1×1 卷积核

    习题一 证明卷积具有交换性 即证明公式 首先 宽卷积定义为 其中 表示宽卷积运算 我们不妨先设一个二维图像和一个二维卷积核 然后对该二维图像X进行零填充 两端各补U 1 和V 1 个零 得到全填充的图像 现有 根据宽卷积定义 为了让x的下标
  • 学 Python 这么久,终于把类函数 & 成员函数 & 静态函数给整明白了!

    前言 学过 Python 的小伙伴应该知道 在类定义过程中 会依据对具体需求的分析 对类函数 成员函数 静态函数进行声明与定义 Python 基础稍弱的同学可能会对这三个函数的名称有些陌生 但你很有可能曾经见到过他们仨 只是没认出来而已 开
  • el-menu动态渲染多级菜单

    思路 创建子菜单递归组件 这里我命名为MySubMenu vue 父组件 引用自定义组件MySubMenu 将菜单数组传递给子组件
  • qt 信号量 linux 信号量 semctl,Linux信号量 共享内存和消息队列

    Linux信号量 共享内存和消息队列 Linux信号量 共享内存和消息队列 1 信号量 使用信号量可以实现进程间同步 主要函数定义 include int semctl int sem id int sem num int command
  • Chisel 手册 英文版

    Chisel Manual Jonathan Bachrach Huy Vo Krste Asanovi EECS Department UC Berkeley jrb huytbvo krste eecs berkeley edu Apr
  • HuTool 工具类简单使用

    官方文档 https hutool cn docs 简介 Hutool是一个小而全的Java工具类库 通过静态方法封装 降低相关API的学习成本 提高工作效率 使Java拥有函数式语言般的优雅 让Java语言也可以 甜甜的 Hutool中的
  • Python爬虫实战案例——第三例

    文章中所有内容仅供学习交流使用 不用于其他任何目的 严禁将文中内容用于任何商业与非法用途 由此产生的一切后果与作者无关 若有侵权 请联系删除 起点中文网月票榜加密字体处理 字体加密的原理 就是将一种特定的字体库来代替浏览器本身的字体库显示的