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

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

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

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

基本流程:

  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 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, headers=self.headers)return responseclass 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_urlnovel_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_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()

执行结果:

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

11.Oracle中rollup函数详解

【基本介绍】 【格式】&#xff1a;group by rollup(字段1,字段2,字段3,...,字段n) 【说明】&#xff1a;rollup主要用于分组汇总&#xff0c;如果rollup中有n个字段&#xff0c;则会分别按【字段1】、【字段1,字段2】&#xff0c;【字段1,字段2,字段3】&#xff0c;...&#…

C++编辑修改PDF

PDFWriter是一个易于使用的C创建、修改PDF文档的库 1.创建一个PDF文件 #include #include “PDFWriter.h” int main() { std::cout << “Hello World!\n”; PDFWriter pdfWriter; int retpdfWriter.StartPDF(“D:\mytestwriterpdf.pdf”, ePDFVersion13); if (ret eS…

C++面向对象编程(2)

目录 一. 问题引入 二. 右值引用 1. lvalue/rvalue/prvalue/xvalue 1.1 表达式与对象的概念 1.2 左值与右值 2. moving semantics 2.1 显示绑定 2.2 Move constructors 2.3 Move assignment operator 2.4 实例分析 // TODO Quiz REF 本章简单介绍下move语义的“来…

day03_注释丶关键字丶标识符丶常量

​注释 注释就是使用人类的自然语言对代码的解释和说明。 代码本身和人类的自然语言相比&#xff0c;可读性肯定是要差一些&#xff0c;所以为了更快能够知道代码的含义、作用、需要注意地方&#xff0c;所有程序员都应该养成写注释的好习惯。 由于注释的内容是给程序员看的&…

《HelloGitHub》第 89 期

兴趣是最好的老师&#xff0c;HelloGitHub 让你对编程感兴趣&#xff01; 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 https://github.com/521xueweihan/HelloGitHub 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等&#xff0c;涵盖多种编程语言 …

融合正余弦和柯西变异的麻雀搜索算法(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Error running ‘Tomcat 8.5.29‘ Address localhost:1099 is already in use

一、Error running ‘Tomcat 8.5.29’ Address localhost:1099 is already in use 原因&#xff1a;端口1099被占用了。 二、解决 2.1 解决方法一-结束该端口1099占用 //1-查看端口占用&#xff0c;根据端口号1099&#xff0c;获取PID(进程ID) netstat -ano | findstr "…

stackoverflow问题

Stack Overflow requires external JavaScript from another domain, which is blocked or failed to load. stackoverflow引用了谷歌中被屏ajax.googleapis.com的jquery.min.js文件。“https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js” 方案1.打开网站…

字节一面:你能讲一下跨域吗

前言 最近博主在字节面试中遇到这样一个面试题&#xff0c;这个问题也是前端面试的高频问题&#xff0c;作为一名前端开发工程师&#xff0c;我们日常开发中与后端联调时一定会遇到跨域的问题&#xff0c;只有处理好了跨域才能够与后端交互完成需求&#xff0c;所以深入学习跨域…

docker 04.更加重要的命令

之前的都是基础命令&#xff0c; 前台交互进程和后台守护进程&#xff1a; 重新进入容器&#xff1a; docker中的导入导出&#xff1a; docker中的拷贝到&#xff1a;

ubuntu学习(五)----读取文件以及光标的移动

1、读取文件函数原型介绍 ssize_t read(int fd,void*buf,size_t count) 参数说明&#xff1a; fd: 是文件描述符 buf:为读出数据的缓冲区&#xff1b; count: 为每次读取的字节数&#xff08;是请求读取的字节数&#xff0c;读上来的数据保存在缓冲区buf中&#xff0c;同时文…

ubuntu学习(四)----文件写入操作编程

1、write函数的详解 ssize_t write(int fd,const void*buf,size_t count); 参数说明&#xff1a; fd:是文件描述符&#xff08;write所对应的是写&#xff0c;即就是1&#xff09; buf:通常是一个字符串&#xff0c;需要写入的字符串 count&#xff1a;是每次写入的字节数…

小程序input的placeholder不垂直居中的问题解决

input的placeholder不垂直居中&#xff0c;input设置高度后&#xff0c;使用line-height只能使输入的文字垂直居中&#xff0c;但是placeholder不会居中&#xff0c;反而会偏上。 首先placeholder样式自定义 有两种方法&#xff0c;第一种行内样式&#xff1a; <input ty…

sql server 备份到网络共享

场景&#xff1a;sql server服务器A将数据库备份文件备份到服务器B 1&#xff09;服务器B创建共享目录 这里我将 D:\ProDbBak 共享&#xff0c;并且Everyone完全控制 2&#xff09;sql server服务器A能够访问服务器B共享目录&#xff0c;并且能完全控制 3&#xff09;修改服务…

c语言每日一练(12)

前言&#xff1a;每日一练系列&#xff0c;每一期都包含5道选择题&#xff0c;2道编程题&#xff0c;博主会尽可能详细地进行讲解&#xff0c;令初学者也能听的清晰。每日一练系列会持续更新&#xff0c;暑假时三天之内必有一更&#xff0c;到了开学之后&#xff0c;将看学业情…

基于Axios完成前后端分离项目数据交互

一、安装Axios npm i axios -S 封装一个请求工具&#xff1a;request.js import axios from axios// 创建可一个新的axios对象 const request axios.create({baseURL: http://localhost:9090, // 后端的接口地址 ip:porttimeout: 30000 })// request 拦截器 // 可以自请求…

Git分布式版本控制系统与github

第四阶段提升 时 间&#xff1a;2023年8月29日 参加人&#xff1a;全班人员 内 容&#xff1a; Git分布式版本控制系统与github 目录 一、案例概述 二、版本控制系统 &#xff08;一&#xff09; 本地版本控制 &#xff08;二&#xff09;集中化的版本控制系统 &…

系统架构:软件工程

文章目录 资源知识点自顶向下与自底向上形式化方法结构化方法敏捷方法净室软件工程面向服务的方法面向对象的方法快速应用开发螺旋模型软件过程和活动开放式源码开发方法功用驱动开发方法统一过程模型RUP基于构件的软件开发UML 资源 信息系统开发方法 知识点 自顶向下与自底…

基于 Debian 12 的 Devuan GNU+Linux 5 为软件自由爱好者而生

导读Devuan 开发人员宣布发布 Devuan GNULinux 5.0 “代达罗斯 “发行版&#xff0c;它是 Debian GNU/Linux 操作系统的 100% 衍生版本&#xff0c;不包含 systemd 和相关组件。 Devuan GNULinux 5 基于最新的 Debian GNU/Linux 12 “书虫 “操作系统系列&#xff0c;采用长期支…