python脚本爬取字体文件的实现方法

yizhihongxing

Python脚本爬取字体文件可以分为以下几个步骤:

  1. 获取字体文件的URL或者本地字体文件的路径
  2. 下载字体文件
  3. 解析字体文件中的映射表(map)信息
  4. 解析需要反爬的文本,并将对应的加密text和已知的明文text进行映射
  5. 替换被加密的文本为明文
  6. 可选:将替换后的文本保存为一个新的HTML页面或者PDF文件

下面是两个示例:

示例1:爬取腾讯视频网站的字体文件并解密被加密的文本

Step 1:打开网页并获取字体文件的URL

以腾讯视频网站为例,在Chrome浏览器中打开任意一个视频页面,右键单击页面中的非链接文本区域,选择“检查”,进入浏览器的开发者工具界面,切换到“Network”选项卡,在浏览器中选择任意一个视频,可以发现浏览器中发出了一个类似的请求:

https://puui.qpic.cn/vfont/yyxbDOwrrG1QcJLAdJ9gpw/241

这个请求中,包含了一个字体文件的URL路径,将该路径复制下来备用。

Step 2:下载字体文件并解析映射表

编写Python脚本,使用requests模块下载该字体文件,然后使用fontTools工具包解析出其中的映射表信息,如下所示:

from fontTools.ttLib import TTFont
import requests

font_url = "https://puui.qpic.cn/vfont/yyxbDOwrrG1QcJLAdJ9gpw/241"

# 首先下载字体文件到本地
response = requests.get(font_url)
with open("font.ttf", "wb") as f:
    f.write(response.content)

# 使用fontTools解析字体文件并获取映射表信息
font = TTFont("font.ttf")
glyf_order = font.getGlyphOrder()[2:]
map_table = font.getBestCmap()
uni_list = []
for i in range(2, len(glyf_order)):
    code_hex = glyf_order[i].replace("uni", "&#x") + ";"
    uni_list.append(chr(map_table[code_hex]))

Step 3:解密加密文本并替换

在腾讯视频网站上,文本中被加密的文本通常以类似“”的形式出现,将该字符替换为对应的明文即可解密被加密文本。

# 需要处理的加密文本
enc_text = "Ste osn"

# 映射加密字符与明文
enc_list = ["", "", "", "", ""]
dec_list = ["S", "t", "e", "a", "n"]
text_map = str.maketrans("".join(enc_list), "".join(dec_list))

# 替换加密文本为明文
dec_text = enc_text.translate(text_map)

示例2:爬取安居客二手房信息,并将结果保存为PDF文件

Step 1:获取网页中的字体文件和加密文本占位符

以安居客网站的二手房页面为例,使用Chrome浏览器打开该页面,在开发者工具中可以发现页面中所有的字体文件都是以Data URI形式内嵌在网页的CSS代码中的。

同时,页面中有很多被加密的数字文本,这些文本都使用了相同的字体文件。在开发者工具的“Elements”选项卡中选中其中的一段加密文本占位符,可以看到类似以下的CSS代码:

.wl-2{
        font-family: normal !important;
        font-weight: 400;
        font-style: normal;
        color: #64b4ff;
        position: relative;
        font-size: 18px;
        letter-spacing: 1px;
        line-height: 30px;
        display: inline-block;
 }
 .wl-2::after{
    content: '5';
        font-family:"Arial",serif !important;
        font-weight: 400;
        font-style: normal;
        font-size: 42px;
        position: absolute;
        top: -16px;
        left: 0px
 }
 .wl-2::before{
    content:'秒';
        font-family:"&sjb-22276cf7a8ad5beecc1d03f7f6c8a6c5",serif !important;
        font-weight: 400;
        font-style: normal;
        font-size: 16px;
        position: absolute;
        right: -22px;
        top: 0;
 }

其中,加密的数字文本是通过伪元素::before和::after进行绝对布局,并调用不同的字体文件进行显示。

可以观察到,字体文件的路径在伪元素::before的内容内容中,而加密的数字则在伪元素::after的content属性中。

Step 2:解析伪元素中的字体文件,并将加密数字替换为明文

利用BeautifulSoup库解析网页,并使用CSS选择器找到加密数字所在的伪元素。

然后,通过正则表达式从伪元素的content属性中截取出加密数字,并从字体文件中解析出对应的明文。

最后,将原文本中的加密数字替换为解密后的明文即可完成解密。

import re 
import requests
from bs4 import BeautifulSoup
from fontTools.ttLib import TTFont
from io import BytesIO
import pdfkit

def get_html(url):
    # 获取HTML代码
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110"
    }
    response = requests.get(url, headers=headers)
    html = response.text
    return html

def decrypt_text(html):
    # 解析字体文件
    font_urls = []
    bs = BeautifulSoup(html, "html.parser")
    css_urls = bs.select("link[rel='stylesheet']")
    for css in css_urls:
        css_url = css["href"]
        if "aosfont" in css_url:
            font_urls.append(css_url)

    font_map = {}
    for font_url in font_urls:
        response = requests.get(font_url)
        font_data = BytesIO(response.content)
        font = TTFont(font_data)
        cmap = font.getBestCmap()
        for k, v in cmap.items():
            if v.startswith("uni"):
                font_map[v] = chr(int(k))

    # 解密数字
    enc_nums = bs.select(".wl-2::after")
    for enc_num in enc_nums:
        enc_str = enc_num.text
        for k, v in font_map.items():
            enc_str = enc_str.replace(k, v)
        enc_num.string = enc_str

    return str(bs)

url = "https://sz.fang.anjuke.com/loupan/all/p1/"
html = get_html(url)
html = decrypt_text(html)

pdfkit.from_string(html, 'out.pdf')

运行上述脚本,会自动爬取安居客网站的第一页二手房信息并保存为PDF文件out.pdf。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python脚本爬取字体文件的实现方法 - Python技术站

(0)
上一篇 2023年6月3日
下一篇 2023年6月3日

相关文章

  • Python内置random模块生成随机数的方法

    Python 内置的 random 模块是用来生成随机数的,它包含了许多函数,可以生成各种类型的随机数。下面我们来详细讲解一下如何使用 Python 内置的 random 模块生成随机数。 导入 random 模块 在使用 random 模块前,必须先导入该模块。可以使用如下代码导入 random 模块: import random 生成随机整数 rando…

    python 2023年6月3日
    00
  • 为Python程序添加图形化界面的教程

    添加图形化界面是一个对于Python程序进行增强和提升用户体验的好方法。Python有很多优秀的图形化界面工具包,比如 PyQt、Tkinter、wxPython 等。 本攻略将介绍如何使用 Tkinter 创建基本的 Python 图形化用户界面。以下是详细步骤: 步骤1: 导入必要的库 首先,我们需要导入 Tkinter 库。 import tkinte…

    python 2023年5月30日
    00
  • python socket多线程实现客户端与服务器连接

    下面是详细的讲解。 Python Socket 多线程实现客户端与服务器连接 简介 Socket编程是指在不同计算机节点间使用网络进行数据通信的方法。 Python提供了socket模块,通过该模块可以轻松实现socket通信。 在Python中使用socket的过程中,我们常常使用多线程来实现客户端与服务器的连接。 本文将详细介绍Python Socket…

    python 2023年5月19日
    00
  • python中的对数log函数表示及用法

    下面是Python中的对数log函数表示及用法的完整攻略。 1. 对数的基础知识 对数是数学中的一个重要概念,其中以10为底的对数被称为常用对数,以e为底的对数被称为自然对数。在Python中,可以使用math模块中的log()函数进行对数计算。其中,log10()函数表示以10为底的对数,log()函数表示以e为底的对数。 2. log()函数的用法及示例…

    python 2023年6月3日
    00
  • Python爬虫爬取有道实现翻译功能

    下面是“Python爬虫爬取有道实现翻译功能”的完整攻略: 简介 本文将介绍如何使用Python编写爬虫程序,爬取有道翻译网站的翻译结果。我们将使用Python的Requests库发送网络请求,解析HTML文档使用BeautifulSoup库,并使用正则表达式提取数据。 爬取流程 发送网络请求:使用Requests库发送POST请求,注意POST请求需要传输…

    python 2023年5月18日
    00
  • 聊聊Numpy.array中[:]和[::]的区别在哪

    当我们使用Numpy库进行数组操作时,我们经常会遇到使用“[:]”和“[::]”的情况,它们看起来很相似,但在使用时有不同的含义和用途。 使用“[:]” “[:]”用于对Numpy数组进行切片操作,可以理解为把整个数组进行复制。具体而言,“[:]”表示从数组的第一个元素开始直到最后一个元素结束,相当于选取整个数组。 下面是一个使用“[:]”的示例: impo…

    python 2023年6月5日
    00
  • Python list与NumPy array 区分详解

    Python list 与 NumPy array 区分详解 Python中的列表(list)和NumPy中的数组(array)都是常用的数据结构,但它们之间有很多区别。本文将详细讲解Python list与NumPy array的区别。 Python list Python中的列表是一种可变的有序序列,可以存储任意数量的任意类型的数据。列表使用方括号[]来…

    python 2023年5月13日
    00
  • python xml解析实例详解

    Python XML解析实例详解 XML(eXtensible Markup Language)是一种标记语言,常用于存储和传输数据。Python提供了多种解析XML文档的库,本文将介绍如何使用Python解析XML文档。 解析XML文档 Python内置的xml库中提供了两个模块用于解析XML文档: xml.etree.ElementTree:该模块提供了…

    python 2023年6月6日
    00
合作推广
合作推广
分享本页
返回顶部